Explore the object overload technology of PHP 5

Source: Internet
Author: User
Tags array empty execution implement pear php code php programming variable

Object overload technology is introduced in PHP 5, and the possibility of overloading the method __call (), __set () and __get () is discussed in this article. After a brief introduction to the overload theory, we will get to the topic through two examples: The first example is to implement the continuous storage class; The second example is to find a way to implement dynamic Getter/setter.

One, what is Object overload?

When it comes to object overloading in PHP, we distinguish between two types:

Method overload

Property overload

In the case of method overloading, we want to define a magic method __call (), which implements a generic invocation of undefined methods in the corresponding class. This generic method is invoked only if you want to access a method that is not defined in the class. In the absence of method overloading, the following example causes PHP to display a fatal error message: Call to undefined methods Thiswillfail::bar () in/some/directory/example.php on line 9 and the execution of the abortion procedure:

    1. 		
          
    2. Class Thiswillfail {
    3. Public Function foo () {
    4. Return "Hello world!";
    5. }
    6. }
    7. $class = new Thiswillfail;
    8. $class->bar ();
    9. ? >

With the help of method overloading, code can capture such calls and gracefully handle them. Property overloads are about the same as method overloads. In this case, the class redirects read/write operations (also known as proxies) to the properties of the class, which are not explicitly defined in the class. The special method here is __set () and __get (). Depending on the error reporting level, the PHP translator usually accesses an undefined attribute, either sends a notification, or delays and potentially defines the variable.

If the property overload is used, the translator can call __set () when an undefined property is set, and call __get () when accessing an undefined property value. To sum up, the use of overload technology can be used in a dynamic language such as PHP, software development time is greatly shortened.

Ii. examples of persistent storage classes

The following code implements the persistent storage class mentioned above by using the attribute overload technique with less than 50 lines of PHP code. 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 explanation is that the external code can use a class to implement the selection of a row from a database table.

In this way, when the program is running, you can directly access the properties of the class to manipulate the elements (read/fetch) in that row. At the end of the script, PHP is responsible for echoing the updated row data back into the database. Careful reading of the following code will help you understand what a property overload is.

  1. 		
        
  2. Mount Pear's db package
  3. Require_once "db.php";
  4. Class Persistable {
  5. Private $data = Array ();
  6. Private $table = "users";
  7. Public function __construct ($user) {
  8. $this->DBH = Db::connect ("Mysql://user:password@localhost/database");
  9. $query = "SELECT ID, name, email, country from".
  10. $this->table. "WHERE name =?";
  11. $this->data = $this->dbh->getrow ($query, Array ($user),
  12. DB_FETCHMODE_ASSOC);
  13. }
  14. Public Function __get ($member) {
  15. if (Isset ($this->data[$member])) {
  16. return $this->data[$member];
  17. }
  18. }
  19. Public Function __set ($member, $value) {
  20. The ID of the dataset is read-only
  21. if ($member = = "id") {
  22. Return
  23. }
  24. if (Isset ($this->data[$member])) {
  25. $this->data[$member] = $value;
  26. }
  27. }
  28. Public Function __destruct () {
  29. $query = "UPDATE". $this->table. "SET name =?,
  30. email =?, Country =? WHERE id =? ";
  31. $this->dbh->query ($query, $this->name, $this->email,
  32. $this->country, $this->id);
  33. }
  34. }
  35. $class = new Persistable ("Martin Jansen");
  36. $class->name = "John Doe";
  37. $class->country = "United States";
  38. $class->email = "john@example.com";
  39. ? >

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 do not need to know too much about constructor methods, except to invoke it to create an instance of a class, and note that a parameter is used-executes a database based on this parameter. This constructor assigns the result of the query to the 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, and __set () is used to modify undefined property values.

This means that whenever an undefined attribute is read/written from a persistent storage class, these specialized methods are responsible for managing the information in the property array variable $data instead of directly changing the properties of the Class (remember: The variable $data contains a row from the database!).).

The last method in the class is the opposite of __construct ()-The destructor __destruct (). PHP invokes the destructor in the script shutdown phase, typically when PHP script execution is almost over. The destructor writes the information from the $data attribute back to the database. This is exactly what the previous sync (synchronization) terminology means.

As you may have noticed, the code here uses the Database abstraction layer package of pear (DB Abstraction layer package). In fact, this does not matter, through other ways and database communication can also explain the theme of this article.

If you look carefully, you will find that the description of the persistent storage class is relatively simple. The example involves only one database table, not more complex data models, such as the use of left join and other complex database manipulation techniques. However, you do not have to be bound by this constraint, and with the help of attribute overloading, you can use your own ideal database model. With just a little code to add, you can use complex database features in that persistent storage class.

There is also a small problem-no error-handling mechanism is introduced when the query fails in the destructor. It is the nature of the destructor that makes it impossible to display the appropriate error message in this case because building HTML flags is often over before PHP invokes the destructor.

To solve this problem, you can rename the __destruct () to a name like SaveData () and manually execute the method at some point in the calling script. This does not change the concept of a class's persistent storage; it's just a few more lines of code. As a choice, you can also use function error_log () in the destructor to record error messages in the system-wide error logging file. This is how the property overload works. Let's discuss the method overload below.

Third, the method overload example

1. The dynamic Getter/setter method

The following code implements the dynamic Getter/setter method to control the class with the help of the method overload. Here we combine the source code for analysis:

    1. 		
          
    2. Class Dynamicgettersetter {
    3. Private $name = "Martin Jansen";
    4. Private $starbucksdrink = "caramel Cappuccino swirl";
    5. Func
  1. 		tion __call ($method, $arguments) {
  2. $prefix = Strtolower (substr ($method, 0, 3));
  3. $property = Strtolower (substr ($method, 3));
  4. if (empty ($prefix) empty ($property)) {
  5. Return
  6. }
  7. if ($prefix = = "Get" && isset ($this-> $property)) {
  8. return $this-> $property;
  9. }
  10. if ($prefix = = "Set") {
  11. $this-> $property = $arguments [0];
  12. }
  13. }
  14. }
  15. $class = new Dynamicgettersetter;
  16. echo "Name:". $class->getname (). "\ n";
  17. echo "Favourite Starbucks flavour:". $class->getstarbucksdrink (). "\ n";
  18. $class->setname ("John Doe");
  19. $class->setstarbucksdrink ("Classic Coffee");
  20. echo "Name:". $class->getname (). "\ n";
  21. echo "Favourite Starbucks flavour:". $class->getstarbucksdrink (). "\ n";
  22. ? >

Obviously, the two attributes $name and $starbucksdrink are private, which means that they cannot be accessed from the outside of the class. In object-oriented programming, it is very common to implement public getter/setter methods to access or modify the values of non-public properties. These are tedious things to achieve, and they are time-consuming and energy-intensive.

This problem can be solved easily by means of overload. Instead of implementing the Getter/setter method for each attribute, a generic __call () method is implemented. This means that when an undefined getter/setter method such as SetName () or Getstarbucksdrink () is invoked, PHP does not produce a fatal error and is aborted, but instead executes (or proxies to) the Magic __call () method. This is a brief introduction, below we to __call () for an in-depth analysis.

2. Detailed analysis of the __call () method

The first parameter of __call () is the original and not yet determined method (such as SetName), and the second parameter is a one-dimensional array of numeric indices that contains all the parameters of the original method. Calling an undefined method with two arguments ("Martin" and "42") produces the following array:

    1. 		$class->thismethoddoesnotexist ("Martin", 42);
    2. /guide The second parameter of __call ()
    3. Array
    4. (
    5. [0] => Martin
    6. [1] => 42
    7. )

Within Method __call (), if the original method starts with a get or set, a calculation is performed to determine whether the code calls a Getter/setter method. Also, this method further analyzes the other component of the method name (minus the three characters that started), because the string that follows is the name of the property that Getter/setter references.

If a getter/setter is indicated in the method name, the method either returns the corresponding property value or sets the value of the first parameter of the original method. If not, it does nothing and continues to execute the program as if nothing had happened.

3. Achieving the Goals

Essentially, there is a way to allow code to dynamically invoke arbitrary getter/setter methods, as appropriate for any property, and this algorithm exists. This is handy when developing a program prototype in the short term: instead of spending a lot of time implementing getters/setters, developers can focus on modeling APIs and ensure that the application is fundamentally correct. Incorporating the __call () approach into an abstract class may even make your code reusable in future PHP engineering development!

4. Beyond the shortage

There are disadvantages when there are advantages. There are several disadvantages to this approach: larger projects can use tools such as Phpdocumentor to track the API structure. With the dynamic approach described above, all getter/setter methods certainly do not appear in automatically generated documents, which is not necessarily explained.

Another disadvantage is that the code outside the class can access each private property within the class. When using the true Getter/setter method, it is possible to distinguish between private properties that can be accessed by external code and "real" private properties that are not visible outside of the class-because we have method overloads, and there are virtual getter and setter methods available.

Conclusion

This paper analyzes two cases of object overload in PHP 5 through two examples. I hope this article can help you improve the efficiency of PHP programming! At the same time, you should be aware of the shortcomings of this approach.



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.