2010-08-08 59 views
0

我是新來的PHP和目前我正在閱讀Wrox專業PHP 5.PropertyObject Class Help

任何人都可以解釋我下面的代碼?

<? 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; 

    } 
} 

} 
?> 

我無法理解評估器中的代碼get和set方法。

回答

1

__get魔法方法在請求對象的屬性但未聲明或專門分配(對於動態屬性)時調用。此實現:

  • 首先嚐試查看邏輯屬性是否存在作爲名爲$propertyTable的實際聲明屬性中的條目。
  • 如果它不存在,則拋出異常,因此在離開方法,
  • 如果它存在和存在additionaly名爲'get'.$propertyName方法(即,"get"與請求屬性名稱鏈接的),該方法被調用和它的值被返回。
  • 如果它存在但沒有這種方法,它將在聲明的屬性$propertyTable中返回條目的值$propertyName

鑑於此,我認爲你可以將__set列出。請參閱PHP手冊中的Magic Methods

+0

謝謝,我明白了,但你能告訴我什麼是array_key_exits,call_user_func和in_array呢?我試圖在谷歌搜索這些語法,但沒有在我的腦海中。 – Searock 2010-08-08 18:41:15

+0

請參閱http://php.net/array_key_exists,http://php.net/call_user_func和http://php.net/in_array – Artefacto 2010-08-08 18:43:27

+0

+1謝謝,解釋看起來很簡單。 – Searock 2010-08-08 18:47:15

1

這是設置數據庫存儲類的一種非常常見的方式。會發生什麼事是你實例基於PropertyObject對象(如PropertyObject是抽象的)

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

繼承了__get()__set()方法。任何時候通過->運算符訪問對象的數據時,將分別調用__get()__set()方法。

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

__get()方法首先檢查以查看是否有在屬性表中定義(其在這裏模型從數據庫字段),並且如果不存在,拋出異常的密鑰。 然後,get()將查看是否存在用前綴「get」定義的函數。因此,假設foopropertyTable中的關鍵字,那麼__get()會查看我們是否已經定義了方法getfoo,如果有,請爲我們調用並返回其值。

//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 

最後,如果在propertyTable關鍵foo,但沒有名爲getfoo方法,它只會返回數組位置的$m->data,其關鍵是在陣列位置的propertyTable,其關鍵是值的值foo

__set()定義大致相同的方式,但而不是返回存儲在data陣列中,而不是檢查一個添附的「設置」,並且檢查該值,看是否在對象上被設置的值是從任何不同值在data數組,如果是,則在設置新值之前,將屬性名稱添加到changedProperties數組中。

+0

+1感謝您的解釋。 – Searock 2010-08-09 14:45:33