MIKESTOWE.COM

you are here

Weekly PHP Test

What is the output of the following code in PHP 5.3+?
(Answer below poll, special thanks @ircmaxell for sharing)

1
2
3
4
5
6
7
8
9
10
11
12
<?php
namespace Foo;
define('Foo\\TRUE', false, true);
define('Foo\\FALSE', true, true);
if ((1==1) == true) {
echo 'TRUE';
} elseif ((1==1) == false) {
echo 'FALSE';
} else {
echo 'UNKNOWN';
}

Create your free online surveys with SurveyMonkey , the world’s leading questionnaire tool.


Answer: “UNKNOWN”

The key here is that this file is namespaced, meaning that we are operating by default in the \Foo namespace, not the \ Global namespace. After setting the namespace the first thing we do is define \Foo\TRUE as a case insensitive constant with a boolean value of “false.” So far, so good, but where it gets tricky is when we define \Foo\FALSE.

We define \Foo\False in a similar manner, and giving it a value of true… the trick here is we are not giving it the value of boolean true, but rather because we are in the \Foo namespace the value of the \Foo\TRUE constant. Essentially, we created a constant in \Foo called “FALSE” with a boolean value of false (again, the value we gave \Foo\True). The other catch here is that we also set the case insensitivity for the \Foo\FALSE constant to \Foo\TRUE, which is false. So not only did we set the constant with a value of boolean false, but also inadvertently made it case sensitive.

Because of this the first two checks in our if/else statement will fail, since we are checking to see if 1==1 is false both times! Here is a quick breakdown of what the code is doing:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
// Declare the namespace
namespace Foo;
// Set \Foo\True to false, case insensitive
define('Foo\\TRUE', \false, \true);
// Set \Foo\False to \Foo\True, case insensitive = false
define('Foo\\FALSE', \Foo\true, \Foo\true);
// Check against \Foo\TRUE because case insensitive
if ((1==1) == true) {
echo 'TRUE';
// Check against \false because \Foo\FALSE is case sensitive
// Wouldn't really matter though, since \Foo\FALSE === false
} elseif ((1==1) == false) {
echo 'FALSE';
// 1==1 returns true... so here we are :)
} else {
echo 'UNKNOWN';
}

If we wanted to use the global namespace for our true/ false constants, we would need to place the backslash in front of them such as \true or \false. See how just adding the backslash (using the global constant instead of the \Foo constant changes the result:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
namespace Foo;
define('Foo\\TRUE', \false, \true);
define('Foo\\FALSE', \true, \true);
if ((1==1) == true) {
echo 'TRUE';
} elseif ((1==1) == false) {
echo 'FALSE';
} else {
echo 'UNKNOWN';
}
Echos out "FALSE"
1
2
3
4
5
6
7
8
9
10
11
12
<?php
namespace Foo;
define('Foo\\TRUE', false, true);
define('Foo\\FALSE', true, true);
if ((1==1) == \true) {
echo 'TRUE';
} elseif ((1==1) == \false) {
echo 'FALSE';
} else {
echo 'UNKNOWN';
}
Echos out "TRUE"

Share this Page:
Facebook Twitter Linkedin Reddit Tumblr Email

Leave a Reply

Your email address will not be published. Required fields are marked *