php-7 - PHP 的飞船操作符 <=> 如何处理不可比操作数?

PHP 7 中将添加飞船操作符。我不确定它在某些极端情况下是如何工作的。
$a <=> $b 将返回:

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

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

    可以比较哪些变量类型?

    最佳答案

    简单的!在 PHP 内部实现操作符 defers to a function called compare_function 的拉取请求,所以你只需要阅读 compare_function 的宏重 C 的 200-line implementation ,你就能够理解自己的行为。控制结构只有 4 层深,只有几十个宏和其他函数被调用;应该很容易!

    ...

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

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

    由于 type juggling ,PHP 中的大多数类型都可以与其他类型进行有意义的比较。在这种情况下,飞船运算符(operator)的行为方式将与 <==> 一致。

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

    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 < $b0 如果 $a == $b1 如果 $a > $b

    但是如果 <==> 都没有返回真,那么宇宙飞船就会混淆并返回 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)

    不可比类型的结果显然没有帮助,并且会混淆任何期望宇宙飞船运算符(operator)一致地对不同类型的值进行排序的事情。因此,不要在可能进行此类无意义比较的情况下使用它。