3

I'am litte bit confused about the the functinning of the spaceship operator on string. In the documentation they say that comparisons are performed according to PHP's usual type comparison rules but not yet clear to me! I looked at this stackoverflow question and did some tests but still confused.

Here is the code I tested:

<?php

$str1 = "aaa";
$str2 = "aaaa";

echo $str1 <=> $str2, PHP_EOL; // -1

$str1 = "baaaaaa";
$str2 = "abbb";

echo $str1 <=> $str2, PHP_EOL; // 1

$str1 = "aaaaaaa";
$str2 = "bbbb";

echo $str1 <=> $str2, PHP_EOL; // -1

How it uses the ASCII values? Thank you for help.

Houssem ZITOUN
  • 644
  • 1
  • 8
  • 23

4 Answers4

4

Compare two expressions.

For string it uses the ASCII values.

It returns -1, 0 or 1 when first expression is respectively less than, equal to, or greater than second expression.

// Integers
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1
 
// Floats
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1
 
// Strings
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1
 
echo "a" <=> "aa"; // -1
echo "zz" <=> "aa"; // 1
 
// Arrays
echo [] <=> []; // 0
echo [1, 2, 3] <=> [1, 2, 3]; // 0
echo [1, 2, 3] <=> []; // 1
echo [1, 2, 3] <=> [1, 2, 1]; // 1
echo [1, 2, 3] <=> [1, 2, 4]; // -1
 
// Objects
$a = (object) ["a" => "b"]; 
$b = (object) ["a" => "b"]; 
echo $a <=> $b; // 0
 
$a = (object) ["a" => "b"]; 
$b = (object) ["a" => "c"]; 
echo $a <=> $b; // -1
 
$a = (object) ["a" => "c"]; 
$b = (object) ["a" => "b"]; 
echo $a <=> $b; // 1
 
// not only values are compared; keys must match
$a = (object) ["a" => "b"]; 
$b = (object) ["b" => "b"]; 
echo $a <=> $b; // 1
Manash Kumar
  • 995
  • 6
  • 13
2

When you use on strings, it will go from left to right, and compare each character in the given string to finds a first difference, then it will comparing the ASCII value of this just found different character. So:

"aaa" < "aaaa" // because 4th char: '' < 'a'
"baaaaaa" > "abbb" // because 1st char 'b' > 'a'
"aaaaaaa" < "bbbb" // because 1st char 'a' < 'b'

And, it is a simple string spaceship operator

$str1 <=> $str2 will return :
1 if $str1 > $str2
-1 if $str1 < $str2
0 if $str1 = $str2
2

The String comparison is based on the ASCII code of each letter and the alphabetical order.

All the strings starting with lower case letters will be greater than strings starting with uppercase letters (because in ASCII, uppercase letters are represented by numbers from 65 to 90, while lowercase letters code are from 97 to 122)

The comparison is done letter by letter and is stopped as soon as two letters of the same position are different.

This, combined with the alphabetical order will give for example:

// "a" comes before "aa" so:
 "a" < "aa"
// and
"a" <=> "aa" === -1

// "b" comes after "B" so:
"b" > "B"
// and
"b" <=> "B" === 1

"Aa" === "Aa"
// and
"Aa" <=> "Aa" === 0

// Because uppercase < lowercase
// "Abb" comes before "abb"
"Abb" < "abb"
"Abb" <=> "abb" === -1

// Because uppercase < lowercase
"Abb" < "a"
"Abb" <=> "a" === -1

// Because uppercase < lowercase
"Bbb" < "a"
"Bbb" <=> "a" === -1

//
"Cbb" > "Baa"
"Cbb" <=> "Baa" === 1
Prince Dorcis
  • 955
  • 7
  • 7
0

I read all the answers but it was insufficient for me as the topic for me is how PHP does things internally. So I searched and searched and it turns out that PHP uses the comparison with the operator <=> on strings, character by character and it stops when there is only one different character and this with ASCII codes as follows:

<?php

$str1 = "aaaaaaa";
$str2 = "bbbb";

echo $str1 <=> $str2, PHP_EOL; // -1

print_r(unpack("C*", $str1));
print_r(unpack("C*", $str2));


// output
 Array
(
    [1] => 97
    [2] => 97
    [3] => 97
    [4] => 97
    [5] => 97
    [6] => 97
    [7] => 97
)
Array
(
    [1] => 98
    [2] => 98
    [3] => 98
    [4] => 98
)

which explains why $str1 <=> $str2 === -1.

Houssem ZITOUN
  • 644
  • 1
  • 8
  • 23