On: PHP as a Weird Thing

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.

Leave a Reply