The 3 different equals

Learn the 3 different equals with practical examples, diagrams, and best practices. Covers php, comparison, operators development techniques with visual explanations.

Understanding PHP's Three Equality Operators: ==, ===, and <=> (Spaceship)

Hero image for The 3 different equals

Explore the nuances of PHP's comparison operators: loose equality (==), strict equality (===), and the combined comparison operator (<=>), to write more robust and predictable code.

In PHP, comparing values is a fundamental operation, but it's not always as straightforward as it seems. PHP offers several ways to compare values, each with its own behavior and implications. Understanding the differences between the loose equality operator (==), the strict equality operator (===), and the combined comparison operator (<=>, often called the 'spaceship operator') is crucial for preventing unexpected bugs and writing reliable code.

Loose Equality (==): The Value Matcher

The loose equality operator (==) checks if two values are equal after performing type juggling (type conversion) if their types differ. This means PHP will attempt to convert one or both operands to a common type before making the comparison. While this can sometimes be convenient, it often leads to surprising results, especially when dealing with different data types.

<?php

// Numeric vs. String
var_dump(10 == '10'); // true (string '10' is converted to integer 10)
var_dump(0 == 'hello'); // true (string 'hello' is converted to 0)

// Boolean vs. Numeric/String
var_dump(true == 1); // true
var_dump(false == 0); // true
var_dump(false == ''); // true
var_dump(false == null); // true

// Null vs. Other types
var_dump(null == false); // true
var_dump(null == ''); // true

// Array vs. Other types
var_dump([] == false); // true
var_dump([1] == true); // true

?>

Examples of loose equality (==) with type juggling.

Strict Equality (===): The Type and Value Matcher

The strict equality operator (===) checks if two values are equal AND if they are of the same type. Unlike ==, === does not perform any type juggling. If the types of the operands are different, the comparison will immediately return false. This makes === much more predictable and generally safer to use, as it avoids the implicit conversions that can lead to unexpected outcomes.

<?php

// Numeric vs. String
var_dump(10 === '10'); // false (integer vs. string)
var_dump(0 === 'hello'); // false (integer vs. string)

// Boolean vs. Numeric/String
var_dump(true === 1); // false (boolean vs. integer)
var_dump(false === 0); // false (boolean vs. integer)
var_dump(false === ''); // false (boolean vs. string)

// Null vs. Other types
var_dump(null === false); // false (null vs. boolean)
var_dump(null === ''); // false (null vs. string)

// Array vs. Other types
var_dump([] === false); // false (array vs. boolean)

?>

Examples of strict equality (===) where types must match.

Combined Comparison Operator (<=>): The Spaceship Operator

Introduced in PHP 7, the combined comparison operator (<=>), often called the 'spaceship operator', is a powerful tool for comparing two expressions. It returns an integer: 0 if the operands are equal, 1 if the left operand is greater, and -1 if the right operand is greater. This operator is particularly useful for sorting functions and situations where you need to know not just if values are equal, but also their relative order.

<?php

// Numeric comparisons
var_dump(1 <=> 1);   // 0
var_dump(1 <=> 2);   // -1
var_dump(2 <=> 1);   // 1

// String comparisons
var_dump('a' <=> 'a'); // 0
var_dump('a' <=> 'b'); // -1
var_dump('b' <=> 'a'); // 1

// Mixed types (behaves like loose comparison for type juggling)
var_dump(10 <=> '10'); // 0
var_dump(5 <=> '10');  // -1
var_dump(10 <=> '5');  // 1

// Usage in sorting (example with usort)
$array = [3, 1, 4, 1, 5, 9];
usort($array, function($a, $b) {
    return $a <=> $b;
});
print_r($array); // Output: Array ( [0] => 1 [1] => 1 [2] => 3 [3] => 4 [4] => 5 [5] => 9 )

?>

Examples of the spaceship operator (<=>) for combined comparison.

flowchart TD
    A[Start Comparison] --> B{Are types identical?}
    B -- Yes --> C{Are values identical?}
    B -- No --> D{Is it '==='?}
    D -- Yes --> E[Result: false]
    D -- No (It's '==') --> F[Perform type juggling]
    F --> G{Are juggled values identical?}
    C -- Yes --> H[Result: true]
    C -- No --> E
    G -- Yes --> H
    G -- No --> E
    H --> I[End]
    E --> I

Decision flow for loose vs. strict equality.

Choosing the Right Operator

The choice of comparison operator significantly impacts your code's behavior. Here's a quick guide:

  • Use === (Strict Equality): This should be your default choice. It provides predictable behavior by ensuring both value and type match. It's best for most comparisons, especially when dealing with user input, database results, or API responses where data types are important.
  • Use == (Loose Equality): Only use this when you explicitly intend for PHP to perform type juggling. Common scenarios might include comparing a numeric string to an integer where you're certain the string represents a valid number, or checking if a variable is 'empty' in a very broad sense (e.g., if ($var == false)). However, even in these cases, consider explicit casting or empty() for clarity.
  • Use <=> (Spaceship Operator): This is ideal for sorting functions (usort, uasort) or any situation where you need to determine the relative order of two values (less than, equal to, or greater than) in a single operation. It simplifies comparison logic significantly.