Careful What you Cheat With

I was Googling things to do with the PHP Zend certification and came across one of those dump sites. These are the kinds of places that are supposed to be filled with questions and answers to the exams so that you can cheat at the certifications. I guess if you were a little more generous, you could say that people use them to get an idea of which kinds of questions they ask, but it’s a grey area (for some, not me!).

Anyway, that aside, here’s a question that I read so I figured I would see if I could work out the answer first and then compare it with what they believe it to be. Take a look now and spend a few minutes on it - what do you think the answer is?

What is the output of the following code?

class C {
public $x = 1;
function __construct() { ++$this->x; }
function __invoke() { return ++$this->x; }
function __toString() { return (string) --$this->x; }
$obj = new C();
echo $obj();

A. 0
B. 1
C. 2
D. 3

I’ve left the formatting as-is but did fix a syntax error with a missing bracket. The answer this site gave was…wait for it…D. Um…

If we break it down, let’s see what happens at each step.

Firstly, $x is set to 1.

When the class C is instantiated, the value of $x is incremented. Here, it doesn’t matter if it’s a pre or post-increment, but in this case, it’s pre. So, $x is now equal to 2.

If the invoke() function were to be called, that would return the value of $x, after it had been incremented. At that point, it would be equal to 3.

If the toString() function were called, it would return the value of $x after it had decremented it by 1, and then convert the result into a string.

Calling invoke() and toString() is going to depend on what happens with the object, so let’s take a look at the code outside of the class, now.

It first creates an object with $obj = new C();. So, we know that $x will be equal to 2 because initially it sets the value of $x to 1, and then the constructor increments it.

The next line echos out the value of $obj, which is of type C so this is where we hit upon one of those other functions. In this case, that’s the toString() function since we are echoing the value of the object and when you do that, it will invoke a method of that name to handle the displaying of an object. Remember what that did? It decrements the value of $x, converts it to a string, and then returns it, which will then be displayed on the screen.

So, we went from a value of 2, back to a value of 1, thanks to toString(), which means the answer must be B, right?

Well, slow down cowboy. The dump site actually said the answer was D…Eek.

Let’s run this the PHP interpreter to convince any disbelievers.

> php -a
php > class C { public $x = 1; function __construct() { ++$this->x; } function __invoke() { return ++$this->x; } function __toString() { return (string) --$this->x; } }
php > $obj = new C();
php > echo $obj;
php >

Ta da. The lesson for today is of course, don’t cheat…or don’t trust the internet…or both.

Hi! Did you find this useful or interesting? I have an email list coming soon, but in the meantime, if you ready anything you fancy chatting about, I would love to hear from you. You can contact me here or at stephen ‘at’