thinkphpはどのように反射を利用してフックの方法を実現します

3758 ワード

ThinkPHPフレームワークのコントローラモジュールはどのように前コントローラ、後コントローラを実現し、どのようにパラメータ付きの方法を実行しますか?
PHPシステムに付属しているReflectionClass、ReflectionMethodクラスは、ユーザー定義クラスの中属性、メソッドの権限、パラメータなどの情報を反射することができ、これらの情報によってメソッドの実行を正確に制御することができる.
ReflectionClass:   [HPマニュアル]詳細
主な方法:
hasMethod(string)メソッドが存在するかどうか
getMethod(string)取得方法
ReflectionMethod:   [HPマニュアル]詳細
主な方法:
isPublic()がpublicメソッドかどうか
getNumberOfParameters()取得パラメータ個数
getParamters()パラメータ情報の取得
invoke( object $object [, mixed $parameter [, mixed $... ]] ) 実行方法
invokeArgs(object obj,array args)帯域パラメータ実行方法
インスタンスのデモ
<?php

class BlogAction {



	public function detail() {

		echo 'detail' . "\r
"; } public function test($year = 2014, $month = 4, $day = 21) { echo $year . '--' . $month . '--' . $day . "\r
"; } public function _before_detail() { echo __FUNCTION__ . "\r
"; } public function _after_detail() { echo __FUNCTION__ . "\r
"; } } // detail $method = new ReflectionMethod('BlogAction', 'detail'); $instance = new BlogAction(); // if ($method->isPublic()) { $class = new ReflectionClass('BlogAction'); // if ($class->hasMethod('_before_detail')) { $beforeMethod = $class->getMethod('_before_detail'); if ($beforeMethod->isPublic()) { $beforeMethod->invoke($instance); } } $method->invoke(new BlogAction); // if ($class->hasMethod('_after_detail')) { $beforeMethod = $class->getMethod('_after_detail'); if ($beforeMethod->isPublic()) { $beforeMethod->invoke($instance); } } } // $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!'; }

 
別のコードリファレンス
/**

 *   App   

 */

public function execApp() {



	//   action     

	$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();



	//        

	$action = ACTION_NAME;



	//       

	//call_user_func(array(&$controller, $action)); //    ,        !!!

	try {

		$methodInfo = new \ReflectionMethod($namespaceClassName, $action);

		if ($methodInfo->isPublic() && !$methodInfo->isStatic()) {

			$methodInfo->invoke($controller);

		} else { //       public  ,    

			throw new \ReflectionException();

		}

	} catch (\ReflectionException $e) {

		//          ,   __call    

		$methodInfo = new \ReflectionMethod($namespaceClassName, '__call');

		$methodInfo->invokeArgs($controller, array($action, ''));

	}

	return;

}


ここではhttp://blog.snsgou.com/post-47.htmlから