But what result will we get, and more importantly, why?The result we will get is 7 and 5 respectively. As to why—there are actually three good reasons.First, let's consider the constructor. While we're inside the constructor, we're establishing a reference between this and this->me. In other words, this and this->me are virtually the same thing. But the key element in the sentence was while we're inside the constructor. As soon as the constructor terminates, PHP has the job of assigning the newly created object (the result of new MyFoo, line 28) into obj. Since objects are not special and are treated like any other data type in PHP, assigning X to Y means making Y a copy of X. In other words, obj becomes a copy of new MyFoo, that is, a copy of the this object that we had inside the constructor. What about obj->me? Since it is a reference, it stays intact during the copy process and goes on pointing to the same object as it did before—this that we had inside the constructor. Voila—obj and obj->me are no longer the same thing: Changing one will not affect the other.That was reason number one—and we promised three. Fortunately, you will find the other reasons very similar to the first one. Let's say that miraculously we managed to overcome the problem in the instantiation of the object (line 28). Still, as soon as we assign the return value of CreateObject into global_object, we would bump into the same problem—global_object would become a replica of the return value, and again, global_object and global_object->me wouldn't have been the same (reason number two).But, as a matter of fact, we wouldn't have gone that far, even—we would have broken the reference as soon as we returned from CreateObject as return $obj (line 34, reason number three).So, how can we fix all this? There are two options. Option one is to add ampersands all over the place, as I have in Listing 6.22 (lines 24, 28, 31, and 37). Option two, if you're lucky enough to be using PHP 5, is to thank your good fortune and forget about all this, as PHP 5 takes care of it for you. Still, if it interests you to understand how PHP 5 is taking care of this, read on.Listing 6.22 WTMA syndrome in PHP 4
1    class MyFoo {
2        function MyFoo()
3        {
4            $this->me = &$this;
5            $this->value = 2;
6        }
7
8        function setValue($val)
9        {
10            $this->value = $val;
11        }
12
13        function getValue()
14        {
15            return $this->value;
16        }
17
18        function getValueFromMe()
19        {
20            return $this->me->value;
21        }
22    };
23
24        function &CreateObject($class_type)
25        {
26            switch ($class_type) {
27                case "foo":
28                    $obj =& new MyFoo();
29                    break;
30                case "bar":
31                    $obj =& new MyBar();
32                    break;
33            }
34            return $obj;
35        }
36
37        $global_obj =& CreateObject ("foo");
38        $global_obj->setValue(7);
39
40        print "Value is " . $global_obj->getValue() . "\n";
41        print "Value is " . $global_obj->getValueFromMe() . "\n";PHP 5 is the first version of PHP to treat objects as different beings, separate from all other types of values. From an end user's perspective, this manifests itself in a very clear way—objects in PHP 5 are always passed by reference, even in situations where other types of values (such as integers, strings, or arrays) are passed by value. Most notably, there is no need to use ampersands at any point in order to pass your objects by reference—they do that out of the box.If you read the example, the motivation for making objects behave that way should be obvious. Object-oriented programming makes extensive use of object networks and complex relationships between objects, which requires using references. The transparent replication employed by previous versions of PHP, while making good sense when dealing with strings or arrays, is counterintuitive when we're dealing with objects. Therefore, moving objects by reference by default and creating copies only if explicitly requested makes more sense than the other way around.How is it done?Before PHP 5, all value types in PHP were stored in a special structure called zval (Zend VALue). These values could store simple values, such as numbers or strings, and complicated values, such as arrays or objects. When sent to or returned from functions, these values were duplicated, creating another structure with identical contents in another place in memory.With PHP 5, values are still stored in the same way inside zval structures, except for objects. Objects are located elsewhere, in a place called Object Store, and are each given identification numbers called handles. A zval, instead of storing an object itself, stores a handle of the object. When replicating a zval that holds an object, such as when we're passing an object as a function argument, we no longer copy any data. We simply retain the same object handle and notify the object store that this particular object is now pointed to by another zval. Because the object itself sits in the Object Store, any changes we make to it will be reflected in all of the zval structures that hold its handle. This additional level of indirection makes PHP objects behave as if they're always passed by reference, in a transparent and efficient manner.We can now go back to our example in Listing 6.21, get rid of all of the ampersands, and everything would still work fine. As a special bonus, there's no need even to use an ampersand when we're keeping a reference to ourselves inside the constructor on line 4.