So, today at work I was working on a mileage tracking webform (more on that another day). I took a brief break to clear my head, and stumbled across a very interesting tweet.
I, of course, did not bookmark it at the time because I thought it was a trivial question and a trivial answer.
It is this bit of PHP Code:
$x = 'A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools.'; if( $x['foo']['bar']){ print 'pass'; } else{ print 'no pass'; }
So, on your inspection, what would you think?
A) Print ‘pass’
B) Print ‘no pass’
C) PHP Exception
D) Not Enough To Tell
E) I Don’t Know
Go ahead. Figure it out. I’ll wait.
…
…
…
…
Think you got it?
If you answered C: You’re wrong. If you answered D: You might be right. If you answered B: You’re wrong. If you answered E: You may have been right too.
The correct answer, as of the version of PHP I use, is A. Executing this code, surprisingly, generated “pass”
Color me straight confused.
So I tried to step through the code and understand it.
var_dump($x['foo']);
What would you expect that to return? Because it returns ‘A’.
What.
Ok, fine, $x[‘foo’] is ‘A’. ‘A'[‘bar’] can’t really be true right?
var_dump($x['foo']['bar']);
It returns, weirdly enough, ‘A’ again.
Even more frustrating is this:
if('A'){ print 'pass' } else{ print 'no pass' }
…Which is what it evaluates out to, by the way, returns ‘pass’
That means ‘A’ evaluates to ‘true’ in PHP.
Even more interestingly,
if('A'===TRUE){ print 'pass' } else{ print 'no pass' }
Which returns ‘no pass’. Which is expected, because === means STRICT equivalence, I think. Meaning the two things need to be of the same type.
Ok, I can accept that ‘A’ evaluates to try. Ostensibly. I mean, it hurts. But I can get it.
What I DON’T get is $x[‘foo’] is ‘A’ and ‘A'[‘bar’] is A also, meaning $x[‘foo’][‘bar’] is A.
Nick and I worked through this and we came to a realization.
It must be, somehow, converting ‘foo’ and ‘bar’ to 0. Because $x[0][0] is definitely ‘A’.
So, what could it be?
Integer. Specifically, intval.
intval(‘a string that isn’t an integer’) returns 0.
intval(‘foo’)is 0.
intval(‘bar’) is 0.
$x[intval(‘foo’)][intval(‘bar’)] is $x[0][0] which is ‘A’.
Is that really it?
Could it be?
I don’t know.
But that’s my story, and I’m sticking to it.
Arrays in PHP are weird though.
Or rather, typecasting a string to an array is weird.
If you use a real array, it’s VERY different.
$y = array( 'herp'=>'derp', 'burp'=>'slurp' ); if( $y['foo']['bar']){ print 'pass'; } else{ print 'no pass'; }
Result? ‘no pass’
Since $y[‘foo’] returns null. That means $y[‘foo’][‘bar’] is null.
And null is most certainly not true.
Go figure.
If you know what is actually going on with the $x[‘foo’][‘bar’] stuff (or know the tweet I’m talking about >_>) please reply so we can talk it out!
-M, out.