How Are Arrays Compared When Using the PHP Spaceship Operator (<=>)?

Comparing arrays using the PHP spaceship operator (<=>) follows the same rules as with other comparison operators (as outlined in the official PHP docs) — i.e., the following four rules apply:

  1. Array With Fewer Elements Is Considered Smaller;
  2. Arrays With Same Length, But Different Keys Are Incomparable;
  3. Arrays With Same Length and Keys Return First Non-Equal Result;
  4. Arrays With Same Length and Key/Value Pairs Are Considered Equal.

This can be visualized using the following standard array comparison algorithm (as specified in the official PHP docs):

function standard_array_compare(array $op1, array $op2): int
{
    // 1.1: first array has less items than the second
    if (count($op1) < count($op2)) {
        return -1;
    // 1.2: first array has more items than the second
    } elseif (count($op1) > count($op2)) {
        return 1; // $op1 > $op2
    }

    foreach ($op1 as $key => $val) {
        // 2: key from first array is not found in second
        if (! array_key_exists($key, $op2)) {
            return 1;
        }
        // 3.1: value of first array is less than value in second array for same key
        elseif ($val < $op2[$key]) {
            return -1;
        }
        // 3.2: value of first array is greater than value in second array for same key
        elseif ($val > $op2[$key]) {
            return 1;
        }
    }
    // 4: arrays are equal
    return 0;
}

Generally, for complex arrays, you should avoid comparing them using the spaceship operator (such as when arrays have different keys). In such cases, using a more explicit comparison logic instead might be more readable and easy to understand.

#Array With Fewer Elements Is Considered Smaller

Array with fewer elements is considered smaller. For example:

$a = [1, 2, 3];
$b = [1, 2, 3, 4];

echo $a <=> $b; // -1
echo $b <=> $a; // 1

In this example, the array "$a" has fewer elements, and is, therefore, considered smaller than the array "$b".

Following the same logic, an empty array is always considered smaller than an array with elements:

$a = [];
$b = [1, 2, 3];

echo $a <=> $b; // -1
echo $b <=> $a; // 1

#Arrays With Same Length, But Different Keys Are Incomparable

In arrays of equal length, if a key from the first array is not found in the second array, the arrays are considered incomparable. In this instance, 1 is always returned. For example:

$a = ['a' => 1, 'b' => 2, 'c' => 3];
$b = ['a' => 1, 'b' => 2, 'd' => 4];

echo $a <=> $b; // 1
echo $b <=> $a; // 1

#Arrays With Same Length and Keys Return First Non-Equal Result

If both arrays have the same length and keys, then a sequential, value-by-value, comparison is done. If there's a difference in the values, the comparison stops, and the result is returned. For example:

$a = ['a' => 1, 'b' => 2, 'c' => 4];
$b = ['a' => 2, 'b' => 1, 'c' => 3];

echo $a <=> $b; // -1
echo $b <=> $a; // 1

In this example, the value of array elements with the key "a" differ, so they will be compared and accordingly the array "$a" comes out to be smaller than the array "$b".

Since, the result of the first non-equal comparison is returned, the order of arrays matters, as you can see in the following example:

$a = ['a' => 1, 'b' => 2, 'c' => 4];
$b = ['c' => 3, 'a' => 2, 'b' => 1];

echo $a <=> $b; // -1
echo $b <=> $a; // -1

In this example:

  • $a <=> $b returns -1 because as per sequential, value-by-value, comparison $a['a'] <=> $b['a'] yields the first non-equal result, where $a['a'] is smaller than $b['a'];
  • $b <=> $a returns -1 as well because $b['c'] <=> $a['c'] yields the first non-equal result in sequential value-by-value comparison, where $b['c'] is smaller than $a['c'].

Consider another example, where $a['b'] is greater than $b['b']:

$a = ['a' => 1, 'b' => 2, 'c' => 4];
$b = ['a' => 1, 'b' => 1, 'c' => 3];

echo $a <=> $b; // 1
echo $b <=> $a; // -1

In this example, since $a['a'] and $b['a'] are equal, therefore, the result of $a['b'] and $b['b'] comparison is returned as that's the first non-equal value in the sequential comparison of the array elements.

#Arrays With Same Length and Key/Value Pairs Are Considered Equal

If both arrays have the same key/value pairs, and the same number of elements, regardless of the order, they're considered equal:

// same key/value pairs, length and order
$a = ['a' => 1, 'b' => 2, 'c' => 3];
$b = ['a' => 1, 'b' => 2, 'c' => 3];

echo $a <=> $b; // 0
echo $b <=> $a; // 0
// same key/value pairs and length, but different order
$a = ['a' => 1, 'b' => 2, 'c' => 3];
$b = ['c' => 3, 'a' => 1, 'b' => 2];

echo $a <=> $b; // 0
echo $b <=> $a; // 0

This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.