More about members overloading: triggering automatically the “__get()” 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.
As I stated before, triggering the “__get()” method behind the scenes via the overloading of a member access is actually a straightforward process. To demonstrate how this can be done, I’ll use the “DataSaver” class that you saw before, but this time I’ll replace its “__set()” method with a “__get()” method.
Keeping in mind this small method replacement, the new definition of the “DataSaver” class is as follows:
class DataSaver{ private $data=array('Element1'=>1,'Element2'=>2,'Element3'=>3); private $dataFile='default_data_file.txt'; // overload __get() method public function __get($index){ echo 'Retrieving element of $data property with index='.$index; if(!$this->data[$index]){ throw new Exception('The referenced element is not valid'); } return $this->data[$index]; } // 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 you’ll certainly agree, the above class isn’t rocket science at all. In simple terms, all that I did was replace the previous “__set()” method with a concrete definition of the new “__get()” method. Closely similar to the example you learned in the previous section, this method can be automatically called by coding the following script:
// example of __get() overloading try{ // instantiate 'DataSaver' object $dataSaver=new DataSaver(); // change value of one element of $data property (calls the __get() method) echo 'The value of the following element property is '.$dataSaver->Element1; } catch(Exception $e){ echo $e->getMessage(); exit(); }
In this specific case, the respective “__get()” method is automatically triggered when a class member access is overloaded by the line below:
echo 'The value of the following element property is '.$dataSaver->Element1;
Of course, after running the code contained inside the “__get()” method, this is the output that I get on my browser:
Retrieving element of $data property with index=Element1 The value of the following property is 1
As you can see, the “__get()” method has been automatically called by simply overloading a class member access. Wasn’t that easy? You bet.
Now that you learned how to trigger the corresponding “__set()” and “__get()” methods individually, the next step consists of demonstrating how these two methods can be integrated in the same class and called appropriately when overloading a couple of property accesses.
To learn more on how this will be achieved, please go ahead and read the next section.