4

PHP 7 中将添加 spaceship 运算符。我不确定它在某些边缘情况下是如何工作的。

$a <=> $b将返回:

  • 1如果 $a > $b
  • 0如果 $a == $b
  • -1如果 $a < $b

如果这些值不具有可比性,会发生什么?

可以比较哪些变量类型?

4

1 回答 1

11

简单的!实现运算符的拉取请求遵循 PHP 内部调用的函数compare_function,因此您只需阅读200 行的宏重 C 实现compare_function,您就可以自己理解行为。控制结构只有 4 层深,只有几十个宏和其他函数被调用;应该很容易!

...

好吧,我承认,我也不够聪明,无法解开所有这些。所以让我们做一些实验,而不是。

如果<,==>可以一致地处理操作数,那么也可以<=>

由于类型杂耍,PHP 中的大多数类型都可以与其他类型进行有意义的比较。在任何情况下,宇宙飞船操作员的行为方式都与和<一致。==>

例如,让我们尝试使用一个字符串和一个 int:

php > var_dump(3 < 'bla');
bool(false)
php > var_dump(3 == 'bla');
bool(false)
php > var_dump(3 > 'bla');
bool(true)
php > var_dump(3 <=> 'bla');
int(1)

或使用null和资源:

php > $fp = fopen('test', 'r');
php > var_dump(null > $fp);
bool(false)
php > var_dump(null == $fp);
bool(false)
php > var_dump(null < $fp);
bool(true)
php > var_dump(null <=> $fp);
int(-1)

或者使用浮点数和数组:

php > var_dump(1.0 > []);
bool(false)
php > var_dump(1.0 == []);
bool(false)
php > var_dump(1.0 < []);
bool(true)
php > var_dump(1.0 <=> []);
int(-1)

在所有这些情况下,结果$a <=> $b正是文档所说的:-1if $a < $b0if$a == $b1if $a > $b

但是如果没有<,==并且>返回 true,则 spaceship 会感到困惑并返回 1

尽管类型强制允许将大多数不同类型的值相互比较,使得 , 和 中的一个$a < $b$a == $b$a > $b,但在少数极端情况下这并不成立。在这些情况下, 的结果$a <=> $b是 1,这不是很有意义或有用。

例如,让我们比较一些不同类的对象:

php > class Foo {}
php > class Bar {}
php > $a = new Foo;
php > $b = new Bar;
php > var_dump($a < $b);
bool(false)
php > var_dump($a == $b);
bool(false)
php > var_dump($a > $b);
bool(false)
php > var_dump($a <=> $b);
int(1)
php > var_dump($b <=> $a);
int(1)

或一些不相等的数组,其中一个都不严格大于另一个:

php > $a = ['foo' => 'bar'];
php > $b = ['bar' => 'foo'];
php > var_dump($a < $b);
bool(false)
php > var_dump($a == $b);
bool(false)
php > var_dump($a > $b);
bool(false)
php > var_dump($a <=> $b);
int(1)
php > var_dump($b <=> $a);
int(1)

<=>也可以抛出警告

如果我们将一个对象与一个 int 进行比较,我们会得到一个警告,就像我们对任何其他比较运算符这样做一样:

php > $a = new stdclass;
php > var_dump($a <=> 1);
PHP Notice:  Object of class stdClass could not be converted to int in php shell code on line 1
int(0)

无法比较的类型的结果显然是没有帮助的,并且会混淆任何期望宇宙飞船操作员始终如一地对不同类型的值进行排序的事情。因此,请勿在可能进行此类无意义比较的情况下使用它。

于 2016-01-16T17:59:42.040 回答