9

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

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,我希望使用来自或至少++使用的字符串__toStringthrow an error

4

5 回答 5

12

操作发生的顺序很重要:

  1. 该变量将作为一个对象被获取,它不会被转换为一个整数(或其他东西)。

  2. ++运算符增加 的lval(长值)zval,但通常不做任何其他事情。对象指针保持不变。内部(fast_)increment_function将被调用,zval其中有一个指向对象的指针,它首先检查类型。如果它是一个对象,它什么也不做。因此,当您zval是一个对象时,它与无操作一样有用。这不会输出任何警告。

  3. 只有这样 echo 指令才对他的参数执行一个字符串转换:该__toString方法被调用并返回20

  4. 20将被输出。

于 2013-05-04T16:52:24.037 回答
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

它将您的对象转换为字符串,该字符串可以转换为数学运算的数字。

于 2013-05-04T14:36:18.717 回答
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 类型的对象执行 '++' 运算符吗?

于 2013-05-04T14:43:46.590 回答
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

我使用这样的东西来格式化表格中的偏移量。

于 2013-06-24T14:25:18.283 回答
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() 中使用字符串转换,但我个人更喜欢以这种方式阅读代码而不是查看引号 - 但我认为这只是一种风格偏好。

将新创建的对象转换为字符串会导致魔术 __toString 方法自动执行,并返回一个数字字符串,当转换为 int 时,您可以显示数字、递增并再次显示。

顺便说一句,++ 和 $number 之间的空格是可以的;我用 b/c 关闭了它,这是我在其他语言(如 C)中所习惯的。

于 2013-11-08T04:48:57.770 回答