我不确定标题应该是什么,但代码应该更好地解释它:
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;
输出:
20
20 <--- Expected 21
20
21
20
21
我知道为什么我会20
而不是21
?即使这样,下面的代码仍然有效:
$i = null ;
echo ++$i ; // output 1
我知道Group
是一个实现__toString
的对象,我希望++
能够处理来自__toString
或至少throw an error
答案 0 :(得分:12)
操作的顺序非常重要:
变量将作为对象获取,不会被转换为整数(或其他内容)。
此++
运算符会增加lval
的{{1}}(长值),但通常没有其他任何内容。对象指针保持不变。将使用zval
调用内部(fast_)increment_function
,zval
具有指向对象的指针,该对象首先检查类型。如果它是一个对象,它什么都不做。因此,当您的zval
是一个对象时,它就像无操作一样有用。这不会输出任何警告。
只有这样,echo指令才会对其参数执行字符串转换:调用__toString
方法并返回20
。
20
将被输出。
答案 1 :(得分:9)
用一点代码回答你的问题。
$number = new Group();
echo gettype($number);
$number = "20";
echo gettype($number);
$number = 20;
echo gettype($number);
将导致
object
string
integer
三种情况:
__toString
方法将在计算实际输出时调用很晚。<强>加成:强>
这将有效:
$number = new Group();
echo 1 + "$number"; // 21
它将您的对象转换为字符串,可以将其转换为数字运算的数字。
答案 2 :(得分:2)
我认为只更改变量的名称可能会更清楚:
class Group {
private $number = 20;
public function __toString() {
return "$this->number";
}
}
$group = new Group();
echo $group;//print 20 as per your __toString function
++ $group;
现在看来显而易见:应该在group ??
类型的对象上做一个'++'运算符答案 3 :(得分:1)
你为什么不:
class Group {
private $number = 0;
public function __construct($number = 0){
$this->number = intval($number);
}
public function __toString() {
return number_format(++$this->number); // pre-increment
}
}
$g = new Group();
echo $g; // 1
echo $g; // 2
我使用这样的方法来格式化表中的偏移量。
答案 4 :(得分:0)
这实际上比您想象的更可行 - 只需要进行更多类型转换,如下所示:
<?php
class Group {
private $number = 20;
public function __toString() {
return (string) $this->number; // replace "" w/string cast
}
}
$number = (int)(string) new Group();
echo $number, PHP_EOL;
echo ++$number, PHP_EOL;
你当然不必在魔法__toString()中使用字符串强制转换,但我个人更喜欢以那种方式阅读代码而不是看引号 - 但我认为这只是一种风格偏好。
将新创建的对象转换为字符串会导致magic __toString方法自动执行,并返回一个数字字符串,当转换为int时,可以显示数字,递增数字并再次显示。
顺便说一句,++和$ number之间的空格是可以的;我把它关闭了b / c,这是我在其他语言中习惯的,比如C。