Overloading a method call: triggering the “__call()” method - PHP
Welcome to the last installment of the series “Overloading classes in PHP.” Comprised of three tutorials, this series shows you how to overload your classes whether you’re using PHP 4 or PHP 5, and explains in detail the implementation of the “__set()”, “__get()” and “__call()” methods, in order to overload property accesses and method calls respectively.
The last practical example that I’ll show you with reference to overloading classes in PHP 5 is completely focused on calling the “__call()” method automatically, when a method call is correctly overloaded. Maybe this sounds confusing, so first I’ll redefine the prior “DataSaver” class to provide a concrete definition for the “__call()” method that I mentioned before. Here’s the source code for this class:
class DataSaver{ private $data=array('Element1'=>1,'Element2'=>2,'Element3'=>3); private $dataFile='default_data_file.txt'; // define __call() method public function __call($method,$arguments){ echo 'Method '.$method. ' has been called with the following arguments:<br />'; foreach($arguments as $argument){ echo $argument.'<br />'; } return array_reverse($arguments);
} // save data to file public function save(){ if(!$fp=fopen($this->dataFile,'a+')){ throw new Exception('Error opening data file'); } fwrite($fp,serialize($this->data)); fclose($fp); } // fetch data from file public function open(){ if(!$contents=file_get_contents($this->dataFile)){ throw new Exception('Error reading from data file'); } return unserialize($contents); } }
As shown above, the “DataSaver” class has an additional “__call()” method, which will be automatically triggered if a method call is overloaded deliberately. Given that, here is a simple script that shows how to overload a method call, which obviously fires up the method in question:
// example of method overloading with __call() method try{ // instantiate 'DataSaver' object $dataSaver=new DataSaver(); // call inexistent 'myMethod()' method (invokes the __call() method) $revData=$dataSaver->myMethod('Element A','Element B','Element C'); echo 'Reversed arguments are as follows:<br />'; foreach($revData as $data){ echo $data.'<br />'; } } catch(Exception $e){ echo $e->getMessage(); exit(); }
If you examine the above example in detail, the corresponding “__call()” method is triggered by the following line:
As you can see, all that this line does is call the “myMethod()” method, in this way enforcing the triggering of “__call()”. Also, it should be noticed that the pertinent arguments passed when overloading a method call will be treated as an array, therefore the output produced by the previous script will be the following:
Method myMethod has been called with the following arguments: Element A Element B Element C Reversed arguments are as follows: Element C Element B Element A
The above listing clearly demonstrates that the “__call()” method has been triggered after overloading a method call, since the array of incoming arguments is first echoed normally, then reversed and finally displayed again, in accordance with the logic implemented by this method.
At this point, I provided you with different practical examples of how to overload members and methods in PHP 5, which can be pretty useful if you want to run custom code defined within “__set()”, “__get()” and “__call()” methods. As I said before, certainly class overloading isn’t one of the strongest features of PHP, but with a little bit of willpower and the appropriate knowledge, you’ll get the most out of it.
Wrapping up
Over this three-part series, you hopefully learned the basics of class overloading in PHP 4/PHP 5. In all the cases I kept the code samples simple and readable, so you can understand more easily how they work. Although overloading objects in PHP seems to be a rather complex topic at first glance, this impression should disappear progressively, if you get more experience on the subject.