2011-05-12 99 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