Loose comparison in PHP. Example of breakable functionality.

Posted by Stanislav Furman  on September 12, 2013

Recently, I have written about comparisons of numbers with floating point. Here is another important lesson that explains why loose comparison may break the business logic in your PHP application.

Look at the following PHP code. It seems pretty clear and straightforward.

<?php
$var = "hello";

switch ($var) {
	case null:
		echo "null";
		break;
	case false:
		echo "false";
		break;
	case 1:
		echo "one";
		break;
	case 2:
		echo "two";
		break;
	case 0:
		echo "zero";
		break;
	case "hello":
		echo "hello";
		break;
	default:
		echo "default";
}

So, which one do you think happens? Don't cheat! :-)

The correct answer is "zero". Not obvious for everyone, right? Here is another example:

<?php
$var = "hello";
switch ($var) {
	case null:
		echo "null";
		break;
	case false:
		echo "false";
		break;
	case true:
		echo "true";
		break;
	case 1:
		echo "one";
		break;
	case 2:
		echo "two";
		break;
	case 0:
		echo "zero";
		break;
	case "hello":
		echo "hello";
		break;
	default:
		echo "default";
}

The result will be 'true'. It happens because PHP goes through all cases one by one and tries to compare values like they would have same type. In other words, when PHP compiler gets to "case 0:" in converts "hello" to integer: (int) "hello" == 0. Or (boolean)"hello" == true. Voila!

Of course, if you move "case 'hello'" before 'case 0', or put integer values in quotes, it will work properly. But still this is a good example of how loose comparison can give you unexpected result.

Refer to the loose comparisons table to get a better idea about how PHP compares values.

Code carefully! ;-)


Leave your comment

Fields with * are required.

* When you submit a comment, you agree with Terms and Conditions of Use.