tags:

views:

24

answers:

2

Hi,

I am new to php and currently I am reading Wrox Professional PHP 5.

Can anyone explain me the following code ?

<? php

abstract class PropertyObject
{
//Stores name/value pairs that hook properties to database field names
protected $propertyTable=array();

//List of properties that have been modified.
protected $changedProperties=array();

//Actual data from the database.
protected $data;

//Any validation errors that might have occured.
protected $errors=array();

public function __construct($arData)
{
     $this->data=$arData;
}

function __get($propertyName)
{
     if(!array_key_exits($propertyName,$this->propertyTable))
     {
          throw new Exception("Invalid property \"$propertyName\" !");
     }

     if(method_exists($this,'get'.$propertyName))
     {
          return call_user_func(array($this,'get'.$propertyName));
     }
     else
     {
          return $this->data[$this->propertyTable[$propertyName]];
     }
}

function __set($propertyName,$value)
{
     if(!array_key_exits($propertyName,$this->propertyTable))
     {
          throw new Exception("Invalid property \"$propertyName\" !")
     }

     if(method_exits($this,'set'.$propertyName))
     {
     return call_user_func(array($this,'set'.$propertyName),$value);
     }
     else
     {
     //If the value of the property really has changed and it's not already in the changedProperties array, add it.

          if($this->propertyTable[$propertyName] !=$value && !in_array($propertyName,$this->changedProperties))
          {
               $this->changedProperties[]=$propertyName;
          }

          //Now set the new value
          $this->data[$this->propertyTable[$propertyName]]=$value;

     }
}

}
?>

I can't understand the code inside assessor get and set methods.

+1  A: 

The __get magic method is called when a property of the object is requested but it wasn't declared or specifically assigned (for dynamic properties). This implementation:

  • First tries to see if the logical property exists as an entry in the actual declared property named $propertyTable.
  • If it doesn't exist, it throws an exception, therefore leaving the method,
  • If it exists and additionaly exists a method named 'get'.$propertyName (i.e., "get" concatenated with the request property name), that method is called and its value is returned.
  • If it exists but there's no such method, it returns the value of the entry with key $propertyName in the declared property $propertyTable.

Given this, I think you can figure __set out. See Magic Methods in the PHP manual.

Artefacto
Thanks, I get it, but can you tell me what array_key_exits,call_user_func and in_array does? I tried searching in google for these syntaxe's but nothing goes in my brain.
Searock
See http://php.net/array_key_exists, http://php.net/call_user_func and http://php.net/in_array
Artefacto
+1 Thanks, the explanation looks simple.
Searock
+1  A: 

This is a really common way of setting up a DB storage class. What happens is you instantiate an object based on PropertyObject (as PropertyObject is abstract)

class MyObj extends PropertyObject {    
}
$m = new MyObj();

Which inherits the __get() and __set() methods. Any time the object's data is accessed via the -> operator, the __get() and __set() methods are called, respectively.

$m->foo;          #calls MyObject::__get('foo');
$m->bar = 'baz';  #calls MyObject::__set('bar','baz');

The __get() method first checks to see if the there is a key defined in the property table (which here models fields from the DB), and if one does not exist, throws an exception. Then, get() will see if there is a function defined with the word 'get' prepended. So, assuming foo was a key in the propertyTable, __get() would see if we had defined a method getfoo, and if we had, call it for us, and return its value.

 //if(method_exists($this,'get'.$propertyName))
 //{
 //     return call_user_func(array($this,'get'.$propertyName));
 //}
$m->foo;  # checks if MyObj::getfoo is defined, and if so, calls it

Lastly, if there is a key foo in the propertyTable but no method named getfoo, it would simply return the value of the array position in $m->data whose key is the value of the array position in propertyTable whose key is foo

__set() is defined much the same way, but rather than returning the value stored in the data array instead checks for a prepended 'set', and checks to see if the value being set on the object is any different from the value in the data array, and if it is, adds the property name to the changedProperties array before setting the new value.

sleepynate
+1 Thanks for the explanation.
Searock