Analysis of the Method of Realizing Hook Based on Reflection in thinkPHP

  • 2021-08-16 23:24:26
  • OfStack

In this paper, an example is given to describe the method of implementing hooks based on reflection in thinkPHP. Share it for your reference, as follows:

How does the controller module of ThinkPHP framework realize the front controller and the back controller, and how to implement the method with parameters?

The ReflectionClass and ReflectionMethod classes in PHP system can reflect the information of attributes, permission and parameters of methods in user-defined classes, and can accurately control the execution of methods through these information.

ReflectionClass:

Main methods used:

hasMethod(string) Is there a method
getMethod(string) Acquisition method

ReflectionMethod:

Main methods:

isPublic() Whether it is an public method
getNumberOfParameters() Get the number of parameters
getParamters() Get parameter information
invoke( object $object [, mixed $parameter [, mixed $... ]] ) Method of execution
invokeArgs(object obj, array args) Execution method with parameters

Example demonstration


<?php
class BlogAction {
  public function detail() {
    echo 'detail' . "\r\n";
  }
  public function test($year = 2014, $month = 4, $day = 21) {
    echo $year . '--' . $month . '--' . $day . "\r\n";
  }
  public function _before_detail() {
    echo __FUNCTION__ . "\r\n";
  }
  public function _after_detail() {
    echo __FUNCTION__ . "\r\n";
  }
}
//  Execute detail Method 
$method = new ReflectionMethod('BlogAction', 'detail');
$instance = new BlogAction();
//  Make authority judgment 
if ($method->isPublic()) {
  $class = new ReflectionClass('BlogAction');
  //  Execute the pre-existing method 
  if ($class->hasMethod('_before_detail')) {
    $beforeMethod = $class->getMethod('_before_detail');
    if ($beforeMethod->isPublic()) {
      $beforeMethod->invoke($instance);
    }
  }
  $method->invoke(new BlogAction);
  //  Execute the post method 
  if ($class->hasMethod('_after_detail')) {
    $beforeMethod = $class->getMethod('_after_detail');
    if ($beforeMethod->isPublic()) {
      $beforeMethod->invoke($instance);
    }
  }
}
//  Execute a method with parameters 
$method = new ReflectionMethod('BlogAction', 'test');
$params = $method->getParameters();
foreach ($params as $param) {
  $paramName = $param->getName();
  if (isset($_REQUEST[$paramName])) {
    $args[] = $_REQUEST[$paramName];
  } elseif ($param->isDefaultValueAvailable()) {
    $args[] = $param->getDefaultValue();
  }
}
if (count($args) == $method->getNumberOfParameters()) {
  $method->invokeArgs($instance, $args);
} else {
  echo 'parameters is wrong!';
}

Another code reference


/**
 *  Execute App Controller 
 */
public function execApp() {
  //  Create action Controller instance 
  $className = MODULE_NAME . 'Controller';
  $namespaceClassName = '\\apps\\' . APP_NAME . '\\controller\\' . $className;
  load_class($namespaceClassName, false);
  if (!class_exists($namespaceClassName)) {
    throw new \Exception('Oops! Module not found : ' . $namespaceClassName);
  }
  $controller = new $namespaceClassName();
  //  Get the current operation name 
  $action = ACTION_NAME;
  //  Perform the current operation 
  //call_user_func(array(&$controller, $action)); //  Actually, this function is enough! ! ! 
  try {
    $methodInfo = new \ReflectionMethod($namespaceClassName, $action);
    if ($methodInfo->isPublic() && !$methodInfo->isStatic()) {
      $methodInfo->invoke($controller);
    } else { //  The operation method is not public Type, throwing an exception 
      throw new \ReflectionException();
    }
  } catch (\ReflectionException $e) {
    //  After an exception occurs in the method call, boot to the __call Method processing 
    $methodInfo = new \ReflectionMethod($namespaceClassName, '__call');
    $methodInfo->invokeArgs($controller, array($action, ''));
  }
  return;
}

For more readers interested in thinkPHP related contents, please check the topics of this site: "ThinkPHP Introduction Tutorial", "thinkPHP Template Operation Skills Summary", "ThinkPHP Common Methods Summary", "codeigniter Introduction Tutorial", "CI (CodeIgniter) Framework Advanced Tutorial", "Zend FrameWork Framework Introduction Tutorial" and "PHP Template Technology Summary".

I hope this article is helpful to the PHP programming based on ThinkPHP framework.


Related articles: