2011-05-12 100 views
0

我有一個ORM類型的類用於更新數據庫中的行。當我將這個類的對象傳遞給我的DAO時,我希望DAO只更新更改的對象中的字段(SQL查詢只應包含更改的列)。現在我只是跟蹤每次調用setter方法並使用它來確定哪些字段已更改。當在PHP中調用任何類的方法時自動調用方法

但這意味着我必須在每個setter方法中重複相同的代碼。在PHP中有沒有辦法可以創建一個方法,該方法在任何時候在類中的任何方法被調用時自動調用?魔術方法只適用於不存在的方法。我想要那樣的東西,但對於現有的方法。

下面是我到目前爲止的代碼:

class Car{ 
    private $id; 
    private $make; 
    private $model; 

    private $modifiedFields = array(); 

    public function getMake(){ return $this->make; } 

    public function setMake($make){ 
    $this->make = $make; 
    $this->modified(__METHOD__); 
    } 

    //getters and setters for other fields 

    private function modified($method){ 
    if (preg_match("/.*?::set(.*)/", $method, $matches)){ 
     $field = $matches[1]; 
     $field[0] = strtolower($field[0]); 
     $this->modifiedFields[] = $field; 
    } 
    } 
} 

這就是我想要的:

class Car{ 
    private $id; 
    private $make; 
    private $model; 

    private $modifiedFields = array(); 

    public function getMake(){ return $this->make; } 

    public function setMake($make){ 
    //the "calledBeforeEveryMethodCall" method is called before entering this method 
    $this->make = $make; 
    } 

    //getters and setters for other fields 

    private function calledBeforeEveryMethodCall($method){ 
    if (preg_match("/.*?::set(.*)/", $method, $matches)){ 
     $field = $matches[1]; 
     $field[0] = strtolower($field[0]); 
     $this->modifiedFields[] = $field; 
    } 
    } 
} 

感謝。

+0

如果你是開放給其他ORM的學說2處理這透明地使用ORM特定代碼不會中毒您的域。基本上它需要更強大的方法來計算變化之前他們承諾,而不是試圖不斷跟蹤他們;這意味着在第一次檢索時保留原始對象的副本。 Doctrine 2文檔:http://www.doctrine-project.org/docs/orm/2.0/en/ – rojoca 2011-05-12 16:01:31

+0

@rojoca不,我不想使用ORM框架。我只需要這個爲這個班級工作。謝謝。 – Michael 2011-05-12 19:38:18

回答

5

誰能把一個通用的方式,所有的setter方法,如:

protected function _setABC

,並定義__call,就像這樣:

<?php 
public function __call($name, $args) { 
    if (method_exists($this, '_', $name)) { 
     return call_user_func_array(array($this, '_', $name), $args); 
    } 
} 
+0

我希望我的二傳手能夠保持公開。謝謝。 – Michael 2011-05-12 19:40:42

+0

@邁克爾吉西的例子,即使功能是公開的,而不是保護的作品。他的意思是暗示你應該將setMake()更改爲_setMake()。當調用類的函數但未知時,將執行__call()函數。所以你仍然可以使用$ obj-> setMake(),它將使用__call('setMake',array(args))。 – 2013-03-25 12:54:51