/* +-------------------------------------------------- --------------------------------+ | = This article is read by Haohappy> | = Classes and Objects 1 Chapter's notes | = Translation + personal experience | = To avoid unnecessary trouble, please do not reprint, thank you | = Criticisms and corrections are welcome, and I hope to make progress together with all PHP enthusiasts! +------- -------------------------------------------------- -----------------------+ */ Section 15--The Development of Zend Engine In the last section of this chapter, Zeev discusses the objects brought by Zend Engine model, specifically mentioning how it differed from the models in previous versions of PHP. When we developed PHP 3 in the summer of 1997, we had no plans to make PHP object-oriented. There was nothing to do with classes and objects. The idea. PHP3 is a purely process-oriented language. However, support for classes was added in the PHP3 alpha version on the evening of August 27, 1997. Adding a new feature to PHP only required minimal discussion at that time, because PHP was explored at that time There are too few people. So from August 1997, PHP took the first step towards an object-oriented programming language. Indeed, this is only the first step. Because there are very few relevant ideas in this design, for objects The support is not strong enough. Using objects in this version is just a cool way to access arrays. Instead of using $foo["bar"], you can use the prettier $foo->bar. Object-oriented approach The main advantage is to store functionality through member functions or methods. A typical code block is shown in Example 6.18. But it is not really that different from the approach in Example 6.19. Listing 6.18 PHP 3 object-oriented programming in PHP3 Object-oriented programming value; } } $obj = new Example(); $obj->PrintValue(); ?> Listing 6.19 PHP 3 structural programming PHP3 Structured programming in PHP3 Above we write in the class The above two lines of code, or explicitly passing the array to the function. But considering that there is no difference between these two options in PHP3, we can still access the array just by using the object model as a "syntactic whitewash". Want to use People who used PHP for object-oriented development, especially those who wanted to use design patterns, quickly found that they hit a wall. Fortunately, at the time (PHP3 era), not many people wanted to use PHP for object-oriented development. PHP4 changed This is the case. The new version brings the concept of reference, which allows different identifiers in PHP to point to the same address in memory. This means that you can use two or more names for the same variable Naming, as in Example 6.20. Listing 6.20 PHP 4 references References in PHP4 Since building a network of objects that point to each other is the basis of all object-oriented design patterns, this improvement is of great significance. When references allow the creation of more As powerful as object-oriented applications are, PHP treats objects the same as other types of data, causing developers great pain. As any PHP4 programmer will tell you, applications will suffer from WTMA (Way Too Many Ampersands&) syndrome. If you want to build a practical application, you will feel extremely painful. Take a look at Example 6.21 and you will understand. Listing 6.21 Problems with objects in PHP 4 Problems with objects in PHP 4 1 class MyFoo { 2 function MyFoo() 3 { 4 $this->me = &$this; 5 $this->value = 5; 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"; Let's discuss it step by step. First, there is a MyFoo class. In the constructor, we give $this->me a reference and set up that we have three other member functions : One sets the value of this->value; one returns the value of this->value; the other returns the value of this->value->me. But isn't --$this the same thing? MyFoo::getValue() Isn't it the same as the value returned by MyFoo::getValueFromMe()? First, we call CreateObject("foo"), which returns an object of type MyFoo. Then we call MyFoo::setValue(7). Finally, we call MyFoo::getValue() and MyFoo::getValueFromMe(), expect a return value of 7. Of course, if we got 7 in every case, the above example wouldn't be the least meaningful example in the book. So I trust you Already guessed it - we won't get two 7s. But what will we get, and more importantly, why? The results we will get are 7 and 5. As for why - three would be nice The reason. First, look at the constructor. When inside the constructor, we establish a reference between this and this->me. In other words, this and this->me are the same thing. But we are inside the constructor. When the constructor ends, PHP has to re-create the object (the result of new MyFoo, line 28) and assign it to $obj. Because objects are not treated specially, just like any other data type, assigning X to Y means that Y is X. A copy. That is, obj will be a copy of new MyFoo, and new MyFoo is an object that exists in the constructor. What about Obj->me? Because it is a reference, it still points to the original unchanged. Object—this. Voila-obj and obj->me are no longer the same thing—change one and the other remains unchanged. That’s the first reason. There are other reasons similar to the first. Miraculously we intend to overcome the problem of instantiating objects (line 28). Once we assign the value returned by CreateObject to global_object, we still run into the same problem - global_object will become a copy of the return value, and again, global_object and global_object ->me will no longer be the same. That's reason number two. But, actually we can't go that far yet — once CreateObject returns $obj, we'll destroy the reference (line 34). That's reason number three. So , how do we correct this? There are two options. One is to add ampersands everywhere, like in Example 6.22 (lines 24, 28, 31, 37). 2. If you are lucky enough to use PHP5, you can Forget all the above, PHP5 will automatically take care of this for you. If you want to know how PHP5 takes this into account, keep reading. Listing 6.22 WTMA syndrome in PHP 4 WTMA syndrome in PHP4 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"; PHP5 is the first PHP version to treat objects as different from other types of data. From a user's perspective, this proves to be very clear - in PHP5, objects are always is passed by reference, while other types of data (such as integer, string, array) are passed by value. Most notably, there is no need to use the & symbol to indicate passing objects by reference. Object-oriented programming widely utilizes Object networks and complex relationships between objects require the use of references. In previous versions of PHP, references needed to be explicitly specified. Therefore, objects are now moved by reference by default, and objects are copied only when explicitly requested to do so. , which is better than before. How is it implemented? Before PHP5, all values were stored in a special structure called zval (Zend Value). These values can be stored in simple values, such as numbers and strings, or complex values such as arrays and objects. When values are passed to or returned from functions, these values are copied, creating a structure with the same content at another address in memory. In PHP5, the value is still stored as a zval In the structure, except for objects. Objects exist in a structure called Object Store, and each object has a different ID. In Zval, the object itself is not stored, but the pointer of the object is stored. When copying a holding object zval structure, for example, if we pass an object as a parameter to a function, we no longer copy any data. We just keep the same object pointer and let another zval notify the Object Store that this specific object currently points to. Because the object itself is located in Object Store, any changes we make to it will affect all zval structures holding pointers to that object. This additional indirection makes it appear as if PHP objects are always passed by reference, in a transparent and efficient way . Using PHP5, we can now go back to Example 6.21 and remove all the ampersands, and everything will still work fine. Not a single ampersand is used when we hold a reference in the constructor (line 4).