Parse error: syntax error, unexpected token ":", expecting "," or ";" in /var/www/html/php8/ch5/L-6-pag-168.php on line 4

<?php
$a = 36; $b = 24; 

echo $a <=> $b ? "They are equal" : "$a is greater than $b" : "$b is greater than  $a"; 
?>

    Also note that the <=> operator returns an integer value (of -1, 0, or 1), not a Boolean; so the results will not be what I think you're expecting, anyway. (For example, if they're equal, it returns 0, which the ? operator will consider to be false).

    I suppose you could do something really ugly with nested ? : operators like this, though I think you'd be better served by some if/else blocks or even a switch/case structure as being more readable:

    echo ($a <=> $b) == 0 ? "They are equal" : (($a <=> $b) == 1 ? "$a is greater than $b" : "$a is less than $b");

    NogDog A match might be even more readable, but...
    Looking at the manual and the language specification, there is no guarantee that its return values will be limited to {-1, 0, 1}.

    I don't know any cases where they aren't, but it's always described as evaluating to an integer that is "less than, equal to, or greater than" zero. The RFC proposing it says it should use {-1, 0, 1}.

    Going deeper, it's implemented using the pre-existing comparison infrastructure (turns out PHP already implemented its order comparisons through one function and then picked out which feature of the result to return). That infrastructure returns {-1, 0, 1} for primitive types, but for built-in objects with ordering semantics it defers to those objects' own implementations and just returns what they return. I haven't found any that implement ordering that return anything different, but I didn't check every existing or future extension. Also, as I said, PHP's comparison operators use the same comparison infrastructure and do so without assuming it produces only {-1, 0, 1}, as do functions like usort that take comparators.

    All of which means for safety (or until the language can be more explicit and restrict the operator's behaviour: a move I would endorse) the result should be tested with <0, =0, or >0. Which is silly because, as already noted, that just puts it through exactly the same comparison infrastructure that it just went through. (Not totally silly, as now it's a comparison of integers instead of a comparison of arbitrary values.)

    Weedpacket

    Interesting...hadn't seen match before. Okay, here's my new code that I hope I never, ever actually use... 🙂

    function lt_eq_gt($a, $b): string {
      return match(max(-1, min(1, $a <=> $b))) {
        -1 => 'less than',
        0  => 'equal to',
        1  => 'greater than'
      };
    }
    
    foreach([[1, 2], ['xyz', 'abc'], [999.351, -0.0123], [5, 5.0]] as $test) {
      echo $test[0]." is ".lt_eq_gt($test[0], $test[1])." ".$test[1]."\n";
    }
    
    /*
    1 is less than 2
    xyz is greater than abc
    999.351 is greater than -0.0123
    5 is equal to 5
    */
    

    🤣

    NogDog

    foreach([[1, 2], ['xyz', 'abc'], [999.351, -0.0123], [5, 5.0]] as $test) {
      echo $test[0]." is ".lt_eq_gt($test[0], $test[1])." ".$test[1]."\n";
    }

    Here's another thing that might be new to you, then:

    foreach([[1, 2], ['xyz', 'abc'], [999.351, -0.0123], [5, 5.0]] as [$left, $right]) {
      echo "$left is ".lt_eq_gt($left, $right)." $right\n";
    }

    Think I'd seen that, but then forgotten it. 🙂

      Write a Reply...