看了下ThinkPHP调用Controller的方法,标准的反射,先检测类有没有这个方法,再检测有没有这个静态方法,但是
__call
方法因为是动态的检测不到,是不是这里应该先判断是否有__call
方法和__callStatic
方法(当然这样的话TP
后面的逻辑就不好处理了)?
public static function invokeMethod($method, $vars = [])
{
if (is_array($method)) {
$class = is_object($method[0]) ? $method[0] : new $method[0](Request::instance());
$reflect = new \ReflectionMethod($class, $method[1]);
} else {
// 静态方法
$reflect = new \ReflectionMethod($method);
}
$args = self::bindParams($reflect, $vars);
self::$debug && Log::record('[ RUN ] ' . $reflect->class . '->' . $reflect->name . '[ ' . $reflect->getFileName() . ' ]', 'info');
return $reflect->invokeArgs(isset($class) ? $class : null, $args);
}
因为我Controller
的相关接口比较多,但是不想去修改前端的请求链接。我想把这个Controller
写轻量点,写了一个工厂方法,把请求转发到不同的类去处理,当然我可以在每个接口去调工厂对应方法。但是感觉太Low了...
想问下大家有没有什么好的方法?谢谢大家。
======== 11-18 14:46 ============
发现不需要配置路由也能动态调用的方法了
在控制器添加
_empty
方法,找不到对应方法时,会调用。
public function _empty()
{
$action = Request::instance()->action();
dump($action);die;
}
ThinkPHP5
的实现代码在App.php
的的module
方法。这里有判断是否有空操作(_empty
方法)。
public static function module(...)
{
...
if (is_callable([$instance, $action])) {
// 执行操作方法
$call = [$instance, $action];
} elseif (is_callable([$instance, '_empty'])) {
// 空操作
$call = [$instance, '_empty'];
$vars = [$action];
} else {
// 操作不存在
throw new HttpException(404, 'method not exists:' . get_class($instance) . '->' . $action . '()');
}
...
}