HomePHP Page 4 - Using Method Call Overloading in PHP 4
Triggering the “__call()” method in the background: overloading a method call - 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.
As I mentioned before, the last example that I’ll show you illustrates how a “__call()” method can be triggered when a method call is overloaded. To clarify this concept, let me tell you that if a specific class has been overloaded by the “overload()” function, then it’s possible to trigger a “__call()” method automatically by using a method call, if the class provides a concrete implementation of it.
Does this sound confusing? Well, in order to simplify things, first I’ll redefine the previous “CookieSaver” class, so it will provide a concrete definition of a “__call()” method. This is how the class now looks:
// define 'CookieSaver' class and implement __call() method 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 cookie via __call () method function __call($method,$arguments){ $expTime=$this->expTimes[$arguments[0]]; setcookie('newCookie',urlencode('This cookie has been set via the __call() method'),time()+$expTime); echo 'Calling '.$method.'() method, which sets a new cookie with an expiration of '.$expTime.' seconds.'; return; } }
As shown above, the “CookieSaver” class looks nearly identical to the previous examples, except that now the class provides a concrete implementation of the “__call()” method. As you can see, the generic structure of this method is the following:
function __call($method,$arguments){ // method definition goes here }
The skeleton of this method should give you a clearer idea, with reference to its input parameters. Yep, you guessed right; when this method is called, it will take up the name of the initial method that was invoked along with an array containing its arguments. Here’s an example that shows the complete process for overloading a method call, which results in the triggering of the previous “_call()” method. Please study the code listed below:
// overload 'CookieSaver' class and implement the __call() method overload('CookieSaver'); // instantiate 'CookieSaver' object $cookieSaver=&new CookieSaver(); // set cookie via __call() method @$cookieSaver->setExpTime('exp1','exp2','exp3');
Things are getting exciting now! If you analyze the above script, you’ll notice the following line:
@$cookieSaver->setExpTime('exp1','exp2','exp3');
What I’m doing here basically is overloading a method call, in this case “setExpTime()”, in order to trigger the corresponding “__call()” method. As you noticed, I’m using a nonexistent method to do this, so I coded the “@” error suppressor before the expression.
Of course, I have to admit the code isn’t elegant at all, but it does trigger the “__call()” method, as shown below:
Calling setexptime() method, which sets a new cookie with an expiration of 900 seconds.
As you saw, the example above shows a crude implementation of overloading a method call, which results in the pertinent “__call()” method being triggered by the PHP parser. Again, I’d like to emphasize that the example focuses on demonstrating the functionality of method call overloading, to the detriment of the code's elegance.
Wrapping up
Over this second part of the series I showed you how to combine the “__set()” and “__get()” methods inside the same class, in order to trigger them when a pair of property accesses are overloaded. Also, you learned how to overload a method call, which triggers the corresponding “__call()” method. Since class overloading isn’t natively supported in PHP 4, I used some code workarounds to keep things working properly.
In the last tutorial, I’ll teach you how to implement object overloading in PHP 5. See you in the next part!