Use Strict Comparisons

ID

php.use_strict_comparisons

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Php

Tags

reliability, suspicious-comparison

Description

Reports loose equality comparisons (==, !=, <>) where one operand is a literal whose loose coercion is bug-prone: null, true/false, 0, the empty string '', the string '0', or another numeric string. Comparisons whose non-literal side is a strpos/stripos search call are left to the dedicated substring-matching rule.

Rationale

PHP’s loose operators coerce both operands to a common type before comparing, which produces surprising results around the falsy values. For example 0 == 'abc' was historically true, '' == null is true, and 0 == '' differs between PHP versions. A function that may return a value or false/0/null therefore gets compared incorrectly. The strict operators === and !== compare type as well as value, so they never juggle and express the intent exactly.

Flagging every == would be far too noisy, so the rule targets only comparisons against these coercion-prone literals, where the trap actually bites.

<?php
function classify($value): string
{
    if ($value == null) {       // FLAW — '' , 0 and false all match null loosely
        return 'empty';
    }
    if ($value == '0') {        // FLAW — 0 == '0' and false == '0' both match
        return 'zero';
    }

    if ($value === null) {      // OK — strict, only real null matches
        return 'null';
    }
    return 'other';
}

Remediation

Replace == with === and !=/<> with !== when comparing against null, a boolean, 0, or an empty/numeric string. If the operands are genuinely of different types and you want a deliberate conversion, make the cast explicit (for example (int) $value === 0) so the intent is clear.