Stupid PHP Tricks: (true == false)

PHP is a weakly-typed language. By that I mean that variables are assigned values without regard to variable type, and implicit conversion at runtime sorts out any conflicts. PHP will happily let you compare a string and an integer, and if the string contains something unexpected, well, you should have paid more attention to data validation.

Given that the most important feature of PHP is the shallow learning curve, and that it is deployed in an environment where everything is a string, it’s (just) possible to argue that this was a good design decision. It allows you to do things like this:

 
$n = "5";
echo 3 + $n;

without getting into lots of tiresome explicit conversion. But the implicit rules are sometimes a little too clever for their own good, and throw up oddities like this:

 
$a = 'string';
$b = 0;
 
if ( $a == true && $b == false && $a == $b )
{
    echo ( 'universe broken' );
}

What’s going on here? Lets look at these three clauses in detail:

  • ( 'string' == true ) because any non-null string evaluates to true when compared with a boolean
  • ( 0 == false ) because the integer 0 undergoes implicit conversion to boolean and evaluates to false
  • Finally, ( 'string' == 0 ) because a string is silently promoted to integer when compared with an integer. If the string is the ASCII representation of a number (eg "123"), it is assigned that value. If it doesn’t contain a number, it is assigned the value 0. So our third clause evaluates as true. Oops…

I routinely use the triple-equals operator (identical) instead of the double-equals operator (equality) now, but it feels and looks like a hack to avoid someone else’s bad design decision biting me. PHP is chock-full of these little oddities.

If you want all the gory details, the type comparison tables are tucked deep inside the PHP Manual.

Update: This post over at ycombinator contains an excellent one-line summary of what I was getting at.

Tags:

This is a good post, but here’s my opinion. It’s not an oddity.

Lower level languages have to enable strict typing because you’re dealing directly with an assembler.

PHP is a high level SCRIPTING language (which is very powerful and fast BTW) that doesn’t need to enable strict typing because it can check as it runs. Its just that as a scripting language where you’re not compiling things BEFORE they run, but rather AS they are running, you don’t want to save your file with a mistake in it as simple as a missed type declaration, or a comparison between two unfamiliar types and then have your entire application break… that would be poor design on the PHP team’s part.

In your example I don’t really think that the 3rd clause is an “Oops”. Why would you want to compare a string to zero, ever? I think that questioning this is bogus in the first place. Although this would be a simple (yet poor) check to validate data in some cases. I don’t see this as a mistake on PHP’s end. Error prevention is important in any language. Yes it enables people to generate sloppy code, but I have seen even sloppier code written in C, Java, and even ASM.

In general this is really up to the programmer to be good at what they do, PHP is just there to allow you to make minor mistakes in a production environment. That’s all you’re talking about, something very minor.

I think that oddity mentioned before is an small concession despite of the fast development you won. That’s the power of scripting languages.

BTW I’m a Java Developer, when I need speed I go for groovy.

Small Remark: “any non-null string evaluates to true when compared with a boolean” is not exactly true, the string ‘0′ also evaluates to false. I think this is a hardcoded exception not due to integer conversion, because the string ‘0.0′ evaluates to true.

Following “johnjo” comment: Don’t you people think it’s a bit sad that people in the industry start looking at PHP and ASP and even actionscript as a programming language rather than a script?!

I heard a while ago from someone that in his company they look at C++ as a low level programming language!

I think that in 10 years from now there will be such a few people that will know C/C++/ASM that we will have super computers, but they will run like 80286 because the OS will be written in ActionScript It starts happening today - not kidding! we have super computers that run a bit slow because too much code that should be written efficiently is written in .NET or Java, meaning using interpreters, meaning losing of efficency!

Anyway, I’m really waiting to the day that drivers programmer will get huge salary because there will be 10 of those in the world! ;-)

CPP, you are being sensationalist. The faster computers get, the more can be done in the background to help development. If you had to code in Assembly language today, we would have really fast, really memory efficient, BROKEN programs. Programming is a battle between the human mind, and the program’s complexity. With languages like .NET, Java, PHP, Python, etc., you are reducing the human brain’s requirement for complexity and trading off a (relatively slight) performance hit. I will take that tradeoff any day.

CPP, um i would rather use php to do websites than use c/c++ or even asm. lets see who finishes creating a db add edit and delete transaction first.

… that is why we have strict comparisons with === and !==

Nice article. :) Stumbled on ya.

Nice, but I wouldn’t go as far to say this makes php a weakly typed language. It’s a good thing. Yes, you can do the above, but the aim of such a language is to create things, so the easier it is to create them (while remaining fast and relatively-low on code), the better the language in my eyes.

Nick - this doesn’t make PHP a weakly typed language any more than having the symptoms of influenza gives you the flu. PHP *is* weakly typed (it’s often referred to as duck-typed - if it quacks like a duck, it’s probably a duck) - this is just a symptom of that.
Maybe you are inferring that the word “weakly” infers this is a bad thing, whereas it doesn’t, it’s just the name for this kind of typing.

I searched Google for php “true == false” and found your post.

The reason was, today I ran into the same example as you did. But in my case, I think it’s even funnier/more stupid.

Just assign $a = ‘00′ and $b = ‘0′. The same conditions apply to these values, and the universe is broken again.

Why in the world do two different strings evaluate to be the same? Who knows.