How does PHP Match exactly evaluate condition?

I’m trying to use this code to print a text based on $num variable value, but when I assign a non-numeric value to it the output is much like I assigned a positive number, shouldn’t the output here be ‘Undefined Value’? I mean why isn’t executing the default case?

$num = ";";
match (true) {
    $num < 0 => print 'negative number',
    $num == 0 => print 'zero',
    $num > 0 => print 'positive number',
    default => 'Undefined Value',
};
//Output: positive number

>Solution :

An simpler test case:

var_dump(';' > 0);
bool(true)

Demo

If we check how comparison operators work, we understand that both operators are converted to numbers, but that isn’t true any more starting on PHP/8.0:

var_dump(';' > 0, (int)';', (int)';' > 0, (float)';', (float)';' > 0);
bool(true)
int(0)
bool(false)
float(0)
bool(false)

Demo

I suspect that documentation needs a fix and current rules are that right side operator is cast to string. As such, ; is 3B in ASCII and 0 is 30 (thus "smaller").

Regarding your code, you could add a numeric check like this:

match (true) {
    is_numeric($num) && $num < 0 => print 'negative number',
    is_numeric($num) && $num == 0 => print 'zero',
    is_numeric($num) && $num > 0 => print 'positive number',
    default => 'Undefined Value',
};

But perhaps a match expression does not provide the leanest syntax for this use case and good old set of if/else can to the work just as fine.

Leave a Reply