Читать книгу PHP This! A Beginners Guide to Learning Object Oriented PHP - Michelle Gosney - Страница 18

Оглавление

Chapter 2: Magic Methods

The magic methods are reserved method names you can use in your classes to utilize special PHP functionality. Magic methods provide access to special PHP behavior. The naming convention used for magic methods is a lower/camel-case letters with two leading underscores.

__construct()

The constructor is a magic method that gets called when the object is instantiated, that is, at the moment an instance a class is created. It is usually the first thing in the class declaration but it does not need to be, it is a method like any other and can be declared anywhere in the class. Recall when I mentioned the parenthesis after the Person class name when we instantiated Mindi?


The reference to the Person() class is the constructor for the $Mindi object. In this particular case the constructor is not implemented because there is nothing inside the parenthesis. By this I mean we don’t initialize any of $Mindi’s properties when we call the constructor. If we do not define a constructor function in our class then the PHP engine will assume that we are using an unimplemented constructor, that is:


Constructors also inherit like any other method. So if we consider our previous inheritance example from the Introduction to OOP, we could add a constructor to the Animal class like this:


Now we can create a class which inherits from the Animal class. Without adding anything into the Cow class, we can declare it and have it inherit from Animal, like this:


If we define a __construct method in the Cow class, then Cow objects will run that instead when they are instantiated. Since there isn’t one, PHP looks to the parent class definition for information and uses that. So we can override, or not, in our new class – very handy.

Invoking Parent Constructor and Destructor

We can get the parent PHP5 constructor and PHP5 Destructor to be invoked in the same way as invoking the parent method, refer to the example below:


__destruct()

Did you spot the file handle that was also part of the constructor? We don’t really want to leave things like that lying around when we finish using an object and so the __destruct method does the opposite of the constructor. It gets run when the object is destroyed, either expressly by us or when we’re not using it any more and PHP cleans it up for us. For the Animal, our __destruct method might look something like this:


__get(), __set(), __isset()

The setting and retrieval process of values of properties within a class that have no a explicit declaration comprises what's known as property overloading in PHP. The __set() function will be called automatically by the PHP engine each time a script attempts to assign a value to a property of a class that hasn't been explicitly declared. The __get() function will be invoked transparently when a script tries to retrieve the value of an undeclared class property. The __isset() function is also invoked when it is called on an undefined property. The purpose of __isset() is to test a property before working with it.

“User” example 1

Say that there's a basic class called "User," which represents, through software, a real-world user. The definition of this sample class would be something like this:


As you can see, the structure of the above "User" class is pretty easy to follow. It's only composed of a few setters and getters, used for setting and retrieving the values assigned to its three declared properties, that is $firstname, $lastname and $email respectively.

So far, nothing strange is happening here, right? What follows is a simple demonstration of how to use this class:


“User” example 2

In the previous example, I created a basic "User" class, whose API allowed us to easily assign and retrieve the values of its declared properties. However, as I expressed earlier, it's possible to shorten its definition and make it more "dynamic" simply by concretely implementing the "__set()" and "__get()" methods.

To demonstrate this concept a bit more, I'm going to redefine this sample class to allow us not only to create new class properties at run time, but retrieve their respective values with extreme ease.

Now that you know what I'm going to do in the next few lines, please examine the modified version of the "User" class. It now looks like this:


In the first case, the "__set()" function will create an undeclared property and assign a value to it, while in the last case, its counterpart "__get()" will retrieve this value if the property has been previously set.

The implementation of these two methods permits us to overload properties in a very simple way. It also makes the class's source code much shorter and more compact. The down side to this is that this process has some disadvantages that must be taken into account. First, and most importantly, the lack of an explicit declaration for each property of the class makes the code harder to read and follow. Second, it's practically impossible for an IDE like Eclipse PDT to keep track of those properties for either commenting or documenting them.


__call()

If a class implements __call(), then if an object of that class is called with a method that doesn't exist __call() is used instead as a substitute. For example:


Now let’s add a method called test() and run it again. Notice that this time test() was called instead of __call():


__sleep()

The __sleep() magic method is called when the object of a class is about to be serialized. Serialization is the process of converting an object into a linear sequence of bytes for storage or transmission to another location over a network. This magic method __sleep() does not accept any parameter and returns an array. The array should contain a list of class members that should be serialized. This means that if you don’t wish to serialize a particular class member, you should not include it in the array. Look at the example below:


In the above example, you can see that the serialized string data only contains the fname of the Employee Object. This is because the __sleep() magic method returned an array containing only the ‘fname’ data member.

__wakeup()

The __wakeup() magic method is the opposite of the __sleep() method and does not accept any parameter nor returns anything. It is responsible for setup operations after an object has been unserialized. Unserialized is the opposite of serialize which means to convert an array into a normal string that you can save in a file, pass in a URL, etc. To unserialize means to take a serialized string and convert it back to an array. The PHP functions Serialize() and Unserialize() are used to perform these operations. Look at the example below:


In the above example, you can see that after the $e object has been serialized, that is converted to a common string, and the output stored in $data variable, we use the $data variable and pass it to the unserialize(). Before the object is unserialized and object created, the __wakeup() method is called.

__clone()

In PHP, objects are always assigned and passed around by reference. Let me explain with a simple example:


Notice that the value of the $first->name property changed from “Number 1” to “Number 2” after I made a copy of the $first object called $second and set the value of $second->name=”Number 2.” This is because both the $first and $second objects actually refer to the same object, the $second object was assigned by reference.

The __clone() magic method can be used to make a copy of an object that doesn’t refer to the object being copied but instead creates a new and completely distinct object. Let me demonstrate how __clone() works by using it in the previous example instead of setting $second = $first.


This time the value of the $first->name did not change after we set a value for $second->name. That is because clone allowed us to make a copy of first that is a totally different object. Hence, now we have two objects not just two references to the same object like we had before.

PHP This! A Beginners Guide to Learning Object Oriented  PHP

Подняться наверх