I am not sure what the title should be, but the code should explain it better:
class Group {
private $number = 20;
public function __toString() {
return "$this->number";
}
}
$number = new Group();
echo $number, PHP_EOL;
echo ++ $number, PHP_EOL;
echo PHP_EOL;
$number = "20";
echo $number, PHP_EOL;
echo ++ $number, PHP_EOL;
echo PHP_EOL;
$number = 20;
echo $number, PHP_EOL;
echo ++ $number, PHP_EOL;
Output:
20
20 <--- Expected 21
20
21
20
21
Any idea why I got 20
instead of 21
? Even then the code below works:
$i = null ;
echo ++$i ; // output 1
I know Group
is an object that implements __toString
, i expected ++
to work with the string from __toString
or at least throw an error
The order in which the operations happen is important:
The variable will be fetched as an object, it won't be casted to an integer (or something else).
This ++
operator increments the lval
(the long value) of the zval
, but does normally nothing else. The object pointer remains the same. The internal (fast_)increment_function
will be called with the zval
which has a pointer to the object, which checks for the type first. If it's an object, it does nothing. So when your zval
is an object, it is as useful as a no-operation. This won't output any warning.
Only then the echo instruction performs a string cast on his arguments: The __toString
method is called and returns 20
.
20
will be output.