HomePHP Page 3 - Using Method Call Overloading in PHP 4
Overloading multiple property accesses: combining the __set() and __get() methods in a single class - PHP
This is part two of the series Overloading classes in PHP. In three tutorials, this series teaches how to overload your classes in PHP 4 by using the overload() PHP built-in function, in conjunction with the implementation of the __set(), __get() and __call() methods, and explores the native support of object overloading in PHP 5.
Combining the __set() and __get() methods into one single class is really a no-brainer process. Once the structure of the class has been defined, its just a matter of adding a concrete implementation for each of the methods. Using the previous CookieSaver class, here is how the two respective methods can be combined:
class CookieSaver{ var $cookieName; var $value; var $expTimes=array('exp1'=>900,'exp2'=>1800,'exp3'=>3600); function CookieSaver($cookieName='defaultCookie',$value='defaultValue'){ if(!is_string($cookieName)){ trigger_error('Invalid cookie name',E_USER_ERROR); } $this->cookieName=$cookieName; $this->value=$value; } // set cookie function setCookie(){ setcookie($this->cookieName,$this->value); } // get cookie function getCookie(){ if(!$cookie=$_COOKIE[$this->cookieName]){ trigger_error('Error retrieving cookie',E_USER_ERROR); } return $cookie; } // set value of property via __set() method function __set($property,$value){ $this->expTimes[$property]=$value; $expTime=$this->expTimes[$property]; setcookie('newCookie',urlencode('This cookie has been set via the __set() method'),time()+$expTime); echo 'Setting new cookie...with expiration of '.$expTime.' seconds.'; return; } // get value of property via __get() method function __get($property){ $expTime=$this->expTimes[$property]; setcookie('newCookie',urlencode('This cookie has been set via the __get() method'),time()+$expTime); echo 'Retrieving new cookie...with an expiration of '.$expTime.' seconds.'; return; } }
As you can see, the above class now includes both the __set() and __get() methods that you saw previously. This comes in very handy for demonstrating how they can be triggered together when the class is properly overloaded by the overload() function.
With reference to this, the following code snippet shows how to overload the class, and how the corresponding __get() and __set() method are automatically called behind the scenes when the same property access is overloaded in turn:
// overload 'CookieSaver' class ( implements __set() and __get() methods) overload('CookieSaver'); // instantiate 'CookieSaver' object $cookieSaver=&new CookieSaver(); // call __set() method and modify $this->expTimes['exp1'] array element @$cookieSaver->exp1=60; // call __get() method and return $this->expTimes['exp1'] array element echo @$cookieSaver->exp1;
In the previous example, when the first property access is overloaded, it gives as output the following message:
Setting new cookie...with an expiration of 60 seconds.
Obviously, this means that the __set() method has been triggered by the PHP parser and a new cookie has been set. In a similar fashion, when the second property access is overloaded, the script displays the following message:
Retrieving new cookie...with an expiration of 900 seconds.
This time, after overloading the second property access, the _get() method has been called, and as a result, the cookie has been retrieved by this method. Also, it should be noted that both property accesses must not be overloaded at the same time. An error will be triggered if you do this, because the two __set() and __get() methods first set a cookie and then display a simple message. As you know, you cannot output anything before handling cookies (at least not directly) when using the HTTP protocol.
Right, at this point youve seen how the two __set() and __get() methods were combined within the same sample class, to be triggered by the PHP interpreter when a couple of property accesses are overloaded. Assuming that you already grasped the core concepts of how to overload a property access, the last example that Im going to show you in this article is aimed at demonstrating how to overload a method call. It will result in the triggering of the respective __call() method.
To learn how this will be achieved, please jump into the next section and keep on reading.