增加“__toString”

时间:2013-05-04 14:24:59

标签: php increment magic-methods

我不确定标题应该是什么,但代码应该更好地解释它:

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

5 个答案:

答案 0 :(得分:12)

操作的顺序非常重要:

  1. 变量将作为对象获取,不会被转换为整数(或其他内容)。

  2. ++运算符会增加lval的{​​{1}}(长值),但通常没有其他任何内容。对象指针保持不变。将使用zval调用内部(fast_)increment_functionzval具有指向对象的指针,该对象首先检查类型。如果它是一个对象,它什么都不做。因此,当您的zval是一个对象时,它就像无操作一样有用。这不会输出任何警告。

  3. 只有这样,echo指令才会对其参数执行字符串转换:调用__toString方法并返回20

  4. 20将被输出。

答案 1 :(得分:9)

用一点代码回答你的问题。

$number = new Group();
echo gettype($number);

$number = "20";
echo gettype($number);

$number = 20;
echo gettype($number);

将导致

object
string
integer

三种情况:

  • 您不能对对象执行任何整数操作,这就是为什么您的代码没有按预期执行的操作。在您尝试使用它进行数学运算失败后,__toString方法将在计算实际输出时调用很晚。
  • 您可以使用字符串进行数学运算,因为PHP会在内部将它们转换回数字
  • 显然你可以用整数
  • 做数学运算

<强>加成:

这将有效:

$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。