Méthodes magiques de surcharge d'opérateurs

L'extension de surcharge d'opérateurs permet de définir comment un objet réagit aux opérateurs. Cela se fait en implémentant les méthodes magiques suivantes :

Opérateurs arithmétiques :

  • $a::__add($b)
  • $a::__sub($b)
  • $a::__mul($b)
  • $a::__div($b)
  • $a::__mod($b)
  • $a::__pow($b)

Opérateurs d'affectation :

  • $a::__assign($b)
  • $a::__assign_add($b)
  • $a::__assign_sub($b)
  • $a::__assign_mul($b)
  • $a::__assign_div($b)
  • $a::__assign_mod($b)
  • $a::__assign_pow($b)
  • $a::__assign_bw_and($b)
  • $a::__assign_bw_or($b)
  • $a::__assign_bw_xor($b)
  • $a::__assign_sl($b)
  • $a::__assign_sr($b)
  • $a::__assign_concat($b)

Opérateurs sur les bits :

  • $a::__bw_and($b)
  • $a::__bw_or($b)
  • $a::__bw_xor($b)
  • $a::__bw_not()
  • $a::__sl($b)
  • $a::__sr($b)

Opérateurs de comparaison :

  • $a::__is_equal($b)
  • $a::__is_not_equal($b)
  • $a::__is_identical($b)
  • $a::__is_not_identical($b)
  • $a::__is_smaller($b)
  • $a::__is_smaller_or_equal($b)
  • $a::__is_greater($b)
  • $a::__is_greater_or_equal($b)
  • $a::__spaceship($b)

Opérateurs d'incrémentation et de décrémentation :

  • $a::__pre_inc()
  • $a::__post_inc()
  • $a::__pre_dec()
  • $a::__post_dec()

Opérateurs de chaînes :

  • $a::__concat($b)

Exemples de surcharge d'opérateurs

Ce qui suit est la classe utilisée pour les tests de l'extension de surcharge d'opérateurs. Elle surcharge tous les opérateurs qu'il est possible de surcharger à des fins de test.

Exemple #1 Classe complète pour la surcharge d'opérateurs

<?php
class OperatorOverloading {
    protected mixed $value;

    //region Méthodes magiques standards
    public function __get(string $name)
    {
        return $this->value;
    }

    public function __set(string $name, mixed $value)
    {
        $this->value = $value;
    }

    public function __construct(mixed $init = null)
    {
        $this->value = $init;
    }
    //endregion

    //region Opérateurs arithmétiques
    public function __add(mixed $val): int|float
    {
        return $this->value + $val;
    }

    public function __div(mixed $val): int|float
    {
        return $this->value / $val;
    }

    public function __mod(mixed $val): int
    {
        return $this->value % $val;
    }

    public function __mul(mixed $val): int|float
    {
        return $this->value * $val;
    }

    public function __pow(mixed $val): int|float
    {
        return $this->value ** $val;
    }

    public function __sub(mixed $val): int|float
    {
        return $this->value - $val;
    }
    //endregion

    //region Opérateurs d'affectation
    public function __assign(mixed $val): mixed
    {
        return $this->value = $val;
    }

    public function __assign_add(mixed $val): mixed
    {
        return $this->value += $val;
    }

    public function __assign_bw_and(mixed $val): mixed
    {
        return $this->value &= $val;
    }

    public function __assign_bw_or(mixed $val): mixed
    {
        return $this->value |= $val;
    }

    public function __assign_concat(mixed $val): string
    {
        return $this->value .= $val;
    }

    public function __assign_div(mixed $val): mixed
    {
        return $this->value /= $val;
    }

    public function __assign_mod(mixed $val): mixed
    {
        return $this->value %= $val;
    }

    public function __assign_mul(mixed $val): mixed
    {
        return $this->value *= $val;
    }

    public function __assign_pow(mixed $val): mixed
    {
        return $this->value **= $val;
    }

    public function __assign_sl(mixed $val): mixed
    {
        return $this->value <<= $val;
    }

    public function __assign_sr(mixed $val): mixed
    {
        return $this->value >>= $val;
    }

    public function __assign_sub(mixed $val): mixed
    {
        return $this->value -= $val;
    }
    //endregion

    //region Opérateurs sur les bits
    public function __bw_and(mixed $val): int
    {
        return $this->value & $val;
    }

    public function __bw_not(): int|string
    {
        return ~$this->value;
    }

    public function __bw_or(mixed $val): int
    {
        return $this->value | $val;
    }

    public function __bw_xor(mixed $val): int
    {
        return $this->value ^ $val;
    }

    public function __sl(mixed $val): int
    {
        return $this->value << $val;
    }

    public function __sr(mixed $val): int
    {
        return $this->value >> $val;
    }
    //endregion

    //region Opérateurs de comparaison
    public function __is_equal(mixed $val): bool
    {
        return $this->value == $val;
    }

    public function __is_greater(mixed $val): bool
    {
        return $this->value > $val;
    }

    public function __is_greater_or_equal(mixed $val): bool
    {
        return $this->value >= $val;
    }

    public function __is_identical(mixed $val): bool
    {
        return $this->value === $val;
    }

    public function __is_not_equal(mixed $val): bool
    {
        return $this->value != $val;
    }

    public function __is_not_identical(mixed $val): bool
    {
        return $this->value !== $val;
    }

    public function __is_smaller(mixed $val): bool
    {
        return $this->value < $val;
    }

    public function __is_smaller_or_equal(mixed $val): bool
    {
        return $this->value <= $val;
    }

    public function __spaceship(mixed $val): int
    {
        return $this->value <=> $val;
    }
    //endregion

    //region Opérateurs d'incrémentation/décrémentation
    public function __post_dec(): mixed
    {
        return $this->value--;
    }

    public function __post_inc(): mixed
    {
        return $this->value++;
    }

    public function __pre_dec(): mixed
    {
        return --$this->value;
    }

    public function __pre_inc(): mixed
    {
        return ++$this->value;
    }
    //endregion

    //region Opérateurs de chaînes
    public function __concat(mixed $val): string
    {
        return $this->value . $val;
    }
    //endregion

}

En utilisant la classe ci-dessus, il est possible de surcharger les opérateurs comme suit :

<?php
$a = new OperatorOverloading(5);
var_dump($a + 10);
var_dump($a - 10);
$b = new OperatorOverloading("Hello");
var_dump($b . " World");

L'exemple ci-dessus va afficher :

int(15)
int(-5)
string(11) "Hello World"