The object overloading technology in PHP5.0 is studied. I am very lucky to read the object overloading technology research in PHP5.0. This article will discuss the possibility of overloading method _ call () ,__ set () and _ get. After a brief introduction to the overload theory, we will go straight to the topic through two examples: "> <LINKhref ="
Text/Zhu Xianzhong compilation
I. INTRODUCTION
Fortunately, object overload technology is introduced in PHP 5.0. This article will discuss the possibility of overloading method _ call () ,__ set () and _ get. After a brief introduction to the overload theory, we will use two examples to go straight to the topic: the first example to implement the continuous storage class; the second example to find a dynamic getter/setter method.
2. what is object overloading?
When talking about object overloading in PHP, we need to distinguish two types:
· Method overload
· Attribute overloading
In case of Method overloading, we need to define a magic method _ call (), which will implement a general call to the undefined method in the corresponding class. This general method is called only when you want to access undefined methods in the class. If there is no method overload, the following example will cause PHP to display a fatal error message: Call to undefined method ThisWillFail: bar () in/some/directory/example. php on line 9 and abortion program execution:
<? Php
Class ThisWillFail {
Public function foo (){
Return "Hello World! ";
}
}
$ Class = new ThisWillFail;
$ Class-> bar ();
?>
With the help of Method overloading, the code can capture such calls and handle them in a decent manner.
The property overload is similar to the method overload. In this case, the class redirects the read/write operation (also called proxy) to the class attributes, which are not explicitly defined in the class. The special methods here are _ set () and _ get (). Depending on the error report level, the PHP translator usually sends a notification when accessing an undefined attribute, or delays and potentially defines this variable. If you use attribute overloading, the translator can call _ set () when setting an undefined attribute, and call _ get () when accessing an undefined attribute value ().
To sum up, the heavy load technology can greatly shorten the software development time when using dynamic languages such as PHP.
The theory is introduced so far, and the specific code is analyzed below.
III. Examples of persistent storage
The following code implements the persistent storage class mentioned above with less than 50 lines of PHP code by using the attribute overload technology. The term persistable means that a class can describe an element from a data structure and maintain synchronization with the bottom storage system. The encoding means that external code can use classes to select a row from a database table. In this way, when the program runs, you can directly access the attributes of the class to manipulate the elements (read/retrieve) in the row ). At the end of the script, PHP will be responsible for sending the updated row data back to the database.
Carefully studying the code below will help you understand what is property overloading.
<? Php
// Mount the <a href = "http://pear.php.net/package/DB/"> DB package </a> of PEAR
Require_once "DB. php ";
Class Persistable {
Private $ data = array ();
Private $ table = "users ";
Public function _ construct ($ user ){
$ This-> dbh = DB: Connect ("mysql: // user: password @ localhost/database ");
$ Query = "SELECT id, name, email, country FROM ".
$ This-> table. "WHERE name =? ";
$ This-> data = $ this-> dbh-> getRow ($ query, array ($ user ),
DB_FETCHMODE_ASSOC );
}
Public function _ get ($ member ){
If (isset ($ this-> data [$ member]) {
Return $ this-> data [$ member];
}
}
Public function _ set ($ member, $ value ){
// Dataset IDs are read-only.
If ($ member = "id "){
Return;
}
If (isset ($ this-> data [$ member]) {
$ This-> data [$ member] = $ value;
}
}
Public function _ destruct (){
$ Query = "UPDATE". $ this-> table. "SET name = ?,
Email = ?, Country =? WHERE id =? ";
$ This-> dbh-> query ($ query, $ this-> name, $ this-> email,
$ This-> country, $ this-> id );
}
}
$ Class = new Persistable ("Martin Jansen ");
$ Class-> name = "John Doe ";
$ Class-> country = "United States ";
$ Class-> email = "john@example.com ";
?>
The first problem you encounter may be _ construct (), which is the new constructor method introduced in PHP 5. In the PHP 4 era, constructors always match their class names. This is no longer the case in PHP 5. You don't need to know too much about the constructor method, except that you can call it to create a class. Note that a parameter is used to execute a database based on this parameter. This constructor assigns the query result to class attribute $ data.
Next, the program defines two special methods: _ get () and _ set (). You should be familiar with them: __get () is used to read undefined property values, __set () is used to modify undefined property values.
This means that no matter when an undefined attribute is read/written from the persistent storage class, these specialized methods are used to manage the information in the attribute array variable $ data, instead of directly changing the attributes of the class (remember: the variable $ data contains a row from the database !).
The last method in the class is the construct () constructor _ destruct (). PHP calls the Destructor in the "script close Stage". This is typically the end of PHP script execution. The Destructor writes the information from the $ data attribute back to the database. This is exactly the meaning of synchronization.
You may have noticed that the code here uses the database abstraction action layer package of PEAR ). In fact, this does not matter. the topic of this article can also be explained through other methods of communication with the database.
If you observe it carefully, you will find that the description of this persistent storage class is relatively simple. The example involves only one database table without considering more complex data models, such as using left join and other complex database operation technologies. However, you do not have to be subject to this constraint. with the help of attribute overloading, you can use your own ideal database model. You only need to add a little code to use complex database features in this persistent storage class.
There is also a small problem-the error handling mechanism is not introduced when the query in the destructor fails. It is the nature of the destructor that makes it impossible to display the corresponding error information in this case, because the HTML build mark is often completed before PHP calls the destructor.
To solve this problem, you can rename _ destruct () to a name like saveData () and manually execute this method somewhere in the script. This does not change the concept of persistent storage of classes; it is just a few more lines of code. You can also use the error_log () function in the destructor to record the error information in the system-specific error record file.
This is the working mechanism of attribute overloading. Next we will discuss Method overloading.
IV. example of Method overloading
1. dynamic Getter/Setter methods
The following code implements the "dynamic" getter/setter method to control the class with the help of Method overloading. The following code is used for analysis:
<? Php
Class DynamicGetterSetter {
Private $ name = "Martin Jansen ";
Private $ starbucksdrink = "Caramel Cappuccino Swirl ";
Function _ call ($ method, $ arguments ){
$ Prefix = strtolower (substr ($ method, 0, 3 ));
$ Property = strtolower (substr ($ method, 3 ));
If (empty ($ prefix) | empty ($ property )){
Return;
}
If ($ prefix = "get" & isset ($ this-> $ property )){
Return $ this-> $ property;
}
If ($ prefix = "set "){
$ This-> $ property = $ arguments [0];
}
}
}
$ Class = new DynamicGetterSetter;
Echo "Name:". $ class-> getName (). "\ n ";
Echo "Favourite Starbucks flavor:". $ class-> getStarbucksDrink (). "\ n ";
$ Class-> setName ("John Doe ");
$ Class-> setStarbucksDrink ("Classic Coffee ");
Echo "Name:". $ class-> getName (). "\ n ";
Echo "Favourite Starbucks flavor:". $ class-> getStarbucksDrink (). "\ n ";
?>
Obviously, both $ name and $ starbucksdrink attributes are private, that is, they cannot be accessed from outside the class. In object-oriented programming, it is quite common to implement public getter/setter methods to access or modify values of non-public attributes. Implementation is monotonous and time-consuming.
This problem can be easily solved by means of Method overloading. Instead of implementing the getter/setter method for each attribute, the above only implements a common _ call () method. This means that when an undefined getter/setter method such as setName () or getStarbucksdrink () is called, PHP will not generate a fatal error and abort, but execute (or proxy) the Magic _ call () method.
This is a brief introduction. next we will perform an in-depth analysis on _ call.
2. detailed analysis of The _ call () method
The first parameter of _ call () is the original and unconfirmed method (such as setName), and the second parameter is a one-dimensional array of numerical indexes, it contains all parameters of the original method. Calling an undefined method with two parameters ("Martin" and 42) will generate the following array:
$ Class-> thisMethodDoesNotExist ("Martin", 42 );
/The second parameter of _ call ()
Array
(
[0] => Martin
[1] => 42
)
Inside method _ call (), if the original method starts with get or set, a calculation is required to determine whether the code calls a getter/setter method. In addition, this method further analyzes another component of the method name (excluding the start three characters), because the subsequent strings represent the name of the property referenced by getter/setter.
If the method name indicates a getter/setter, the method returns the corresponding property value or the value of the first parameter of the original method. If not, it does not do anything and continues to execute the program, as if nothing had happened.
3. goals
Essentially, corresponding to any property, there is a method that allows the code to dynamically call any getter/setter method. this algorithm exists. It is very convenient to develop a program prototype in the short term: it does not take a lot of time to implement getters/setters, developers can focus on modeling APIs and ensure that the application is fundamentally correct. Incorporating the _ call () method into an abstract class may even enable you to reuse code in future PHP engineering development!
4. out of limitations
If there are advantages, there are disadvantages. The preceding method also has several disadvantages: a larger project can use a tool such as phpDocumentor to track the API structure. Using the dynamic method described above, all getter/setter methods will certainly not appear in the automatically generated document, which does not need to be explained.
Another disadvantage is that code outside the class can access every private attribute in the class. When the real getter/setter method is used, it is possible to differentiate between private attributes that can be accessed by external code and "real" private attributes that are invisible to external class-because we have methods to overload them, there are also virtual getter and setter methods available.
V. Conclusion
This article uses two examples to analyze the two situations of object overloading in PHP 5.0. I hope this article will help you improve the efficiency of PHP programming! At the same time, you should also be aware of the shortcomings of this method.