简单!在 PHP 内部实现操作符 defers to a function called compare_function 的拉取请求,因此您只需阅读宏重 C 的 compare_function 的 200-line implementation 即可了解其行为。控制结构只有 4 层深,只有几十个宏和其他函数被调用;应该很容易!
...
好吧,我承认,我也不够聪明,无法解开所有这些。所以让我们做一些实验吧。
如果<、== 和> 可以一致地处理操作数,那么<=> 也可以
感谢type juggling,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 的结果正是文档所说的:-1 如果$a < $b,0 如果$a == $b,1 如果$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)
无法比较的类型的结果显然是没有帮助的,并且会混淆任何期望宇宙飞船操作员一致地对不同类型的值进行排序的事情。因此,请勿在可能会进行此类无意义比较的情况下使用它。