在PHP中调用类的任何方法时自动调用方法

Mic*_*ael 0 php

我有一个ORM类型的类,我用它来更新数据库中的行.当我将此类的对象传递给我的DAO时,我希望DAO只更新更改的对象中的字段(SQL查询应该只包含更改的列).现在我只是跟踪每次调用setter方法并使用它来确定哪些字段发生了变化.

但这意味着我必须在每个setter方法中复制相同的代码.在PHP中是否有一种方法可以创建一个方法,可以在调用类中的任何方法时自动调用该方法?该__call魔术方法仅适用于不存在的方法.我想要这样的东西,但对于现有的方法.

这是我到目前为止的代码:

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;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这就是我要的:

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;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

谢谢.

Yos*_*shi 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);
   }
}
Run Code Online (Sandbox Code Playgroud)