简体   繁体   中英

Automatically call a method when any method of a class is called in PHP

I have a ORM-type class that I use to update rows in the database. When I pass an object of this class to my DAO, I want the DAO to only update the fields in the object that changed (the SQL query should only contain the changed columns). Right now I'm just keeping track of every time a setter method is called and using this to determine which fields changed.

But this means I have to duplicate the same code in every setter method. Is there a way in PHP that I can create a method which is automatically called any time any method in the class is called? The __call magic method only works for non-existent methods. I want something like that, but for existing methods.

Here's the code that I have so far:

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

This is what I want:

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

Thanks.

You could name all your setters in a generic way, like:

protected function _setABC

and define __call as something like:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM