The true oo of PHP4
Author Johan Persson is the developer of the famous Jpgraph Chart library in PHP. This article is a summary of several small problems that the author needs to pay attention to in the PHP4 of object-oriented development.
Translation: Binzy Wu [mail:binzy at justdn Dot COM], the level is limited, welcome to explore. 2004-2-4
Brief introduction
The object of this article is for those who have used the more mature oo [1] language, such as Eiffel, Java, C # [2] or C + + (), to develop a friend (like myself). There is a lot of semantics when using PHP4 for full OO development [3] (semantic)
On the trap [4].
The contents of this article can help to avoid the mistakes I have made.
Reference VS Copy Semantics
This is basically the main source of the error (at least for me). Even in PHP's documentation you can read that PHP4 uses copy semantics more than references (such as other object-oriented languages I know), but this will still keep you in the middle of some minor problems.
The next two sections are used to illustrate two small examples where copying semantics in these two examples may surprise you.
It is important to keep in mind that a variable of a class is not a pointer to a class but the actual class itself [5]. Most problems arise from a misunderstanding of the assignment operator (=), which is that it is an alias to an object, but actually a new copy. For example, suppose $myobj is an instance of a class, and it has a set () method. Then the following code might not work as expected by a C + + (or Java) programmer.
function SomeFunction ($AOBJ) {$AOBJ->set (10);}
...
SomeFunction ($MYOBJ);
...
Now, it's easy to think that the set () method called by the function will work on $myobj. But it's wrong!
What happened was that $myobj was copied as a new, copy of the same as the original object----parameter $aobj. Then when the set () method is called, it only acts on the local copy rather than the original parameter----$MYOBJ.
A variety of the above problems occur in areas that contain direct or indirect (as above) assignment operations.
In order for the function to act as you would expect (perhaps), you have to tell PHP to use a reference to pass the object by using the Modify method declaration, such as:
Function SomeFunction (& $AOBJ)
If you try the above code again, you will find that the set () method will work on the original parameter, because now we create a $myobj alias----$aObj in action.
But you have to be careful, because even the & operator does not save you at any time, as in the example below.
To get a reference from a reference
Suppose you have the following code:
$myObject = new SomeClass (); $myRefToObject = & $myObject;
If we want a copy of the reference now (for some reason), what are we going to do? You may be trying to write because $myreftoobject is already quoted:
$myCopyRefToObject = $myRefToObject;
Are you right? No! PHP creates a new copy of the object referenced by $myreftoobject. If you want to copy a reference to an object, you have to write this:
$myCopyRefToObject = & $myRefToObject;
In the example of C + +, which is equivalent to the example described earlier, a reference is created. is different from PHP. This is an intuitive assumption by an experienced C + + programmer to do the opposite, and this will be the source of small bugs in your PHP program.
Be careful with the resulting indirect (pass-through parameters) or direct problems.
My personal conclusion is that the best way to avoid these semantic traps is to always use references to pass objects or object assignments. This not only improves the speed of operation (less copies of the data), but also makes the semantics more predictable for older dogs like me.
Using references to $this in constructors
Initializing objects as other object Discoveries (Observer[6]) in the constructor of an object is a common pattern. The following lines of code are an example:
Class Bettery
{
function Bettery () {...};
function Addobserver ($method, & $obj)
{
$this->obs[] = Array ($obj, & $method)
}
function Notify () {...}
}
Class Display
{
Function Display (& $batt)
{
$batt->addobserver ("Batterynotify", $this);
}
function batterynotify () {...}
}
However, this does not work properly if you are instantiating objects like this:
$myBattery = new Battery (), $myDisplay = new Display ($myBattery);
The error in doing so is that using $this in the constructor when new does not return the same object. Instead, a copy of the most recently created object is returned. That is, the object being transmitted when calling Addobserver () is not the same as the original object. Then when the battery class tries to notify all its observers (Observer) (by calling their Notify method), it does not invoke the display class we created but rather the class represented by $this (the copy of the display class we created). So if the Notify () method updates Some instance variables, it's not as if the original display class we imagined would be updated because the update is actually a copy. In order for it to work, you must return the constructor to the same object, as symbolized by the original $this. You can add & symbols to the display structure, such as $mydisplay = & new Display ($myBattery);
A direct result is that the client of any display class must understand the implementation details of the display. In fact, this creates a potentially contentious issue: all objects must be built with extra & symbols. As I said, it's basically safe, but ignoring it might get unwanted at some point like the example above.
Another method was used to resolve the jpgraph. That is, you need to "new" an object by adding a so-called two-stage construct that can safely use the "Init ()" Method of the & $this reference (simply because the $this reference in the constructor returns a copy of the object rather than as expected). So the above example would be implemented as follows:
$myBattery = new Battery ();
$myDisplay = new Display ();
$myDisplay->init ($myBattery);
such as the "Linearscale" class in jpgraph.php.
Using the Foreach
Another problem with similar code but different results is the problem of the "foreach" structure. Consider the different versions of the following two loop structures.
Version 1
foreach ($this->plots as $p)
{
$p->update ();
}
...
Version 2
for ($i =0; $i plots); + + $i)
{
$this->plots[$i]->update ();
}
Now is a question worth 10 dollars [7]: Version1==version2?
The surprising answer is: no! This is a small but crucial difference. In version 1, the Update () method will be used for a copy of the object in the "plots[" array. Therefore, the original object in the array is not updated.
The update () method in version 2 will act as expected in the object in the "plots[]" array.
As stated in the first section, this is the result of PHP processing an object instance as the object itself rather than as an object reference.
Moqtada
[1]. oo:object-oriented, object oriented.
[2]. The original text does not have C #, all because Binzy's personal hobby.
[3]. Semantic is translated as "semantic" in this article, please contact Binzy if you have any suggestions.
[4]. C + + has a well-known "C + + Gotchas".
[5]. The class here should refer to instance, which is an instance.
[6]. Refer to "[GoF95]", "Design Patterns".
[7]. There's a very interesting little story about trading:
Someone bought a horse for $60 and sold it for $70, then he bought it for $80 and finally sold it for $90. In this horse deal, he? (a) $10 in compensation; (B) balance of payments; © earned $10; (D) earned $20; (E) earned $30.
This is a simple arithmetic question for students at the University of Michigan psychologist Mel and Burke. As a result, less than 40% of college students are able to make the right answer, and most think they make only $10. In fact, the condition of the problem is very clear, this is two transactions, every time to make 10 dollars, Many people mistakenly think that he has lost $10 when he bought it for $80. The interesting thing is that the same question was raised in another way: a man bought a white horse for $60 and sold it for $70, then bought a black horse for $80 and sold it for $90. In the trading of the horse, he ____ (the same five choices listed). At this point, Another group of college students answered the above questions, and everyone was correct.
http://www.bkjia.com/PHPjc/314503.html www.bkjia.com true http://www.bkjia.com/PHPjc/314503.html techarticle Johan Persson, author of PHP4 's True Oo, is the developer of the famous Jpgraph Chart class library in PHP. This article is the author of a few small issues to be aware of in the PHP4 of object-oriented development of the total ...