[DOC-CVS] [doc-en] master: ext/operator: Add documentation (#4669)

[email protected] ("J. B. Lopez via GitHub") Thu, 25 Jun 2026 17:17:49 +0000
Newsgroups php.doc.cvs
Message-ID <[email protected]>
Author: J. B. Lopez (jb-lopez)
Committer: GitHub (web-flow)
Pusher: jordikroon
Date: 2026-06-25T19:17:46+02:00

Commit: https://github.com/php/doc-en/commit/6043cd25418a3c45c64a4af118ee939c1835251b
Raw diff: https://github.com/php/doc-en/commit/6043cd25418a3c45c64a4af118ee939c1835251b.diff

ext/operator: Add documentation (#4669)

* Add ext/operator documentation

Co-authored-by: Louis-Arnaud <[email protected]>
Co-authored-by: Jordi Kroon <[email protected]>

Changed paths:
  A  reference/operator/book.xml
  A  reference/operator/overloading.xml
  A  reference/operator/setup.xml
  M  appendices/extensions.xml
  M  language/operators.xml


Diff:

diff --git a/appendices/extensions.xml b/appendices/extensions.xml
index 47bd5c6a1a76..e79c1c83694a 100644
--- a/appendices/extensions.xml
+++ b/appendices/extensions.xml
@@ -95,6 +95,7 @@
    <listitem><simpara><xref linkend="book.opcache"/></simpara></listitem>
    <listitem><simpara><xref linkend="book.openal"/></simpara></listitem>
    <listitem><simpara><xref linkend="book.openssl"/></simpara></listitem>
+   <listitem><simpara><xref linkend="book.operator"/></simpara></listitem>
    <listitem><simpara><xref linkend="book.outcontrol"/></simpara></listitem>
    <listitem><simpara><xref linkend="book.parallel"/></simpara></listitem>
    <listitem><simpara><xref linkend="book.parle"/></simpara></listitem>
@@ -352,6 +353,7 @@
     <listitem><para><xref linkend="book.oauth"/></para></listitem>
     <listitem><para><xref linkend="book.oci8"/></para></listitem>
     <listitem><para><xref linkend="book.openal"/></para></listitem>
+    <listitem><para><xref linkend="book.operator"/></para></listitem>
     <listitem><para><xref linkend="book.parallel"/></para></listitem>
     <listitem><para><xref linkend="book.parle"/></para></listitem>
     <listitem><para><xref linkend="ref.pdo-cubrid"/></para></listitem>
diff --git a/language/operators.xml b/language/operators.xml
index 894dd8b228e3..68b5fcfd53d6 100644
--- a/language/operators.xml
+++ b/language/operators.xml
@@ -29,6 +29,11 @@
   exactly how expressions containing several different operators are
   evaluated.
  </para>
+ <simpara>
+  There is a PECL extension that allows for overloading of some operators for
+  objects. For more information, see the <link linkend="book.operator">Operator
+  Overloading for Objects</link> section.
+ </simpara>
 
  &language.operators.precedence;
  &language.operators.arithmetic;
diff --git a/reference/operator/book.xml b/reference/operator/book.xml
new file mode 100644
index 000000000000..4788283f7626
--- /dev/null
+++ b/reference/operator/book.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- $Revision$ -->
+<book xml:id="book.operator" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <?phpdoc extension-membership="pecl" ?>
+ <title>Operator Overloading for Objects</title>
+ <titleabbrev>Operator Overloading</titleabbrev>
+
+ <!-- {{{ preface -->
+ <preface xml:id="intro.operator">
+  &reftitle.intro;
+  <simpara>
+   This extension defines and implements operator overloading for objects.
+   It allows defining how an object reacts when an operator is used on it.
+  </simpara>
+  <simpara>
+   One example of this is creating a collection type object that has the addition
+   operator overloaded to allow adding elements to the collection or adding two
+   collections together.
+  </simpara>
+  <simpara>
+   Another example is creating an enhanced string class that has the multiplication
+   operator overloaded to allow repeating the string a certain number of times.
+  </simpara>
+ </preface>
+ <!-- }}} -->
+ &reference.operator.setup;
+ &reference.operator.overloading;
+</book>
diff --git a/reference/operator/overloading.xml b/reference/operator/overloading.xml
new file mode 100644
index 000000000000..7c623f6f76a2
--- /dev/null
+++ b/reference/operator/overloading.xml
@@ -0,0 +1,340 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- $Revision$ -->
+
+<chapter xml:id="operator.overloading" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <title>Operator Overloading Magic Methods</title>
+ <simpara>
+  The operator overloading extension allows you to define how an object reacts to operators. This is done by implementing the following magic methods:
+ </simpara>
+ <para>
+  Arithmetic operators:
+  <simplelist>
+   <member><literal>$a::__add($b)</literal></member>
+   <member><literal>$a::__sub($b)</literal></member>
+   <member><literal>$a::__mul($b)</literal></member>
+   <member><literal>$a::__div($b)</literal></member>
+   <member><literal>$a::__mod($b)</literal></member>
+   <member><literal>$a::__pow($b)</literal></member>
+  </simplelist>
+ </para>
+ <para>
+  Assignment operators:
+  <simplelist>
+   <member><literal>$a::__assign($b)</literal></member>
+   <member><literal>$a::__assign_add($b)</literal></member>
+   <member><literal>$a::__assign_sub($b)</literal></member>
+   <member><literal>$a::__assign_mul($b)</literal></member>
+   <member><literal>$a::__assign_div($b)</literal></member>
+   <member><literal>$a::__assign_mod($b)</literal></member>
+   <member><literal>$a::__assign_pow($b)</literal></member>
+   <member><literal>$a::__assign_bw_and($b)</literal></member>
+   <member><literal>$a::__assign_bw_or($b)</literal></member>
+   <member><literal>$a::__assign_bw_xor($b)</literal></member>
+   <member><literal>$a::__assign_sl($b)</literal></member>
+   <member><literal>$a::__assign_sr($b)</literal></member>
+   <member><literal>$a::__assign_concat($b)</literal></member>
+  </simplelist>
+ </para>
+ <para>
+  Bitwise operators:
+  <simplelist>
+   <member><literal>$a::__bw_and($b)</literal></member>
+   <member><literal>$a::__bw_or($b)</literal></member>
+   <member><literal>$a::__bw_xor($b)</literal></member>
+   <member><literal>$a::__bw_not()</literal></member>
+   <member><literal>$a::__sl($b)</literal></member>
+   <member><literal>$a::__sr($b)</literal></member>
+  </simplelist>
+ </para>
+ <para>
+  Comparison operators:
+  <simplelist>
+   <member><literal>$a::__is_equal($b)</literal></member>
+   <member><literal>$a::__is_not_equal($b)</literal></member>
+   <member><literal>$a::__is_identical($b)</literal></member>
+   <member><literal>$a::__is_not_identical($b)</literal></member>
+   <member><literal>$a::__is_smaller($b)</literal></member>
+   <member><literal>$a::__is_smaller_or_equal($b)</literal></member>
+   <member><literal>$a::__is_greater($b)</literal></member>
+   <member><literal>$a::__is_greater_or_equal($b)</literal></member>
+   <member><literal>$a::__spaceship($b)</literal></member>
+  </simplelist>
+ </para>
+ <para>
+  Incrementing and decrementing operators:
+  <simplelist>
+   <member><literal>$a::__pre_inc()</literal></member>
+   <member><literal>$a::__post_inc()</literal></member>
+   <member><literal>$a::__pre_dec()</literal></member>
+   <member><literal>$a::__post_dec()</literal></member>
+  </simplelist>
+ </para>
+ <para>
+  String operators:
+  <simplelist>
+   <member><literal>$a::__concat($b)</literal></member>
+  </simplelist>
+ </para>
+ <section>
+  <title>Operator Overloading Examples</title>
+  <simpara>
+   The following is the class that is used in the testing of the operator overloading extension.
+   It overloads all of the possible operators that can be overloaded for testing.
+  </simpara>
+  <example xml:id="operator.overloading.complete-class">
+   <title>Complete class for operator overloading</title>
+   <programlisting role="php">
+<![CDATA[
+<?php
+class OperatorOverloading {
+    protected mixed $value;
+
+    //region Standard magic methods
+    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 Arithmetic Operators
+    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 Assignment Operators
+    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 Bitwise Operators
+    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 Comparison Operators
+    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 Incrementing/Decrementing Operators
+    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 String Operators
+    public function __concat(mixed $val): string
+    {
+        return $this->value . $val;
+    }
+    //endregion
+
+}
+
+]]>
+   </programlisting>
+   <simpara>
+    Using the above class, you can overload the operators as follows:
+   </simpara>
+   <programlisting role="php">
+<![CDATA[
+<?php
+$a = new OperatorOverloading(5);
+var_dump($a + 10);
+var_dump($a - 10);
+$b = new OperatorOverloading("Hello");
+var_dump($b . " World");
+]]>
+   </programlisting>
+   <simpara>
+    The above code will output:
+   </simpara>
+   <screen>
+<![CDATA[
+int(15)
+int(-5)
+string(11) "Hello World"
+]]>
+   </screen>
+  </example>
+ </section>
+</chapter>
diff --git a/reference/operator/setup.xml b/reference/operator/setup.xml
new file mode 100644
index 000000000000..2778b671b803
--- /dev/null
+++ b/reference/operator/setup.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- $Revision$ -->
+
+<chapter xml:id="operator.setup" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
+ &reftitle.setup;
+ <section xml:id="operator.installation">
+  &reftitle.install;
+  <simpara>
+   &pecl.info;
+   <link xlink:href="&url.pecl.package;operator">&url.pecl.package;operator</link>.
+  </simpara>
+  <simpara>
+   Windows users can download prebuilt release binaries from the <link xlink:href="&url.pecl.package;operator">PECL</link> website.
+  </simpara>
+  <simpara>
+   operator releases are hosted by PECL and the source code by
+   <link xlink:href="&url.git.hub;jb-lopez/pecl-php-operator">github</link>.
+  </simpara>
+ </section>
+</chapter>