__get and __set

To set the context for this discussion, remember that we spent some time discussing accessor, or set and get methods, in Chapter 6. There I argued that instance variables should be made private and only retrieved or changed through accessor methods. Doing otherwise violates the object-oriented (OO) principle of data hiding (or encapsulation if you prefer) and leaves instance variables exposed to inadvertent changes.

PHP 5 introduces magic set and get methods for undefined instance variables. Let's see what this means by looking at an example. Suppose you have a class, Person, devoid of any data members or methods, defined as follows:

class Person{
}

PHP allows you to do the following:

$p = new Person();
$p->name = "Fred";
$p->street = "36 Springdale Blvd";

Even though name and street data members have not been declared within the Person class, you can assign them values and, once assigned, you can retrieve those values. This is what is meant by undefined instance variables. You can create magic set and get methods to handle any undefined instance variables by making the following changes to the Person class, as shown inListing 13-1.

Listing 13-1. Defining magic set and get methods
class Person{
    protected ❶$datamembers = array();
    public function ❸__set($variable, $value){
        //perhaps check value passed in
        $this->datamembers[$variable] = $value;
    }
    public function __get($variable){
        return $this->datamembers[$variable];
    }
}
$p = new Person();
$p->❷name = "Fred";

You add ❶ an array to your class and use it to capture any undeclared instance variables. With these revisions, assigning a value to an undeclared data member called ❷ name invokes ❸ the __set method in the background, and an array element with the key name will be assigned a value of "Fred." In a similar fashion the __get method will retrieve name.

Is It Worth It?

Magic set and get methods are introduced as a convenience, but it is certainly questionable whether they are worth the effort. Encouraging the use of undefined data members can easily lead to difficulties when debugging. For instance, if you want to change the value of the name data member of your Person class instance, but misspell it, PHP will quietly create another instance variable. Setting a nonexistent data member produces no error or warning, so your spelling error will be difficult to catch. On the other hand, attempting to use an undefined method produces a fatal error. For this reason, declaring data members to be private (or protected), and ensuring that they are only accessible through declared accessor methods, eliminates the danger of accidentally creating a new unwanted data member. Using declared data members means fewer debugging problems.

Undeclared data members also seem contrary to the principles of OOP. Although you might argue that encapsulation has been preserved because undeclared data members are only accessed indirectly through the magic methods, the real point of accessor methods is to control how instance variables are changed or retrieved. The comment inside the __set method (//perhaps check value passed in) in Listing 13-1 suggests that such controls could be implemented, but in order to do so you would need to know the variable names beforehand—an impossibility given that they are undeclared. Why not just set up properly declared data members?

Allowing undeclared data members also undermines another basic concept of OOP, namely inheritance. It's hard to see how a derived class might inherit undeclared instance variables.

One might argue, though, that these magic methods make PHP easier to use and this convenience offsets any of the disadvantages. After all, the original and continuing impetus behind PHP is to simplify web development. Allowing undeclared data members in PHP 5 is perhaps a necessary evil because doing so keeps backward compatibility with PHP 4. While it's easy to criticize magic set and get methods, in Chapter 16, when discussing the PDORow class, you'll see that these methods can come in very handy.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.22.107