扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
一个最典型的场景,如在同一个应用(thinkphp5是模块)下,A控制器有一个a方法,B控制器的b方法跟a方法类似,这时候如果要减少代码的重复,我们可以直接在b方法中复用a方法的逻辑,最简单的逻辑,就是把a、b的调用的逻辑全部写到公共应用或模块中。但实际上即便所有的逻辑全部写在A、B控制器中,也可以实现调用。
在thinkphp5中框架自带了一个助手函数action。在b方法中调用a方法的代码也很简单:
return action('A/a',[参数]);
假设在home应用下,已经存在Posts控制器的index方法,需要在Pages控制器的index方法中调用。且index可以接受参数name。Posts控制器的示例代码如下:
namespace app\home\controller; use app\common\controller\HomeBase; class Posts extends HomeBase{ public function index($name=''){ return $name; } }
那么控制器Pages的示例代码如下:
namespace app\home\controller; use app\common\controller\HomeBase; class Pages extends HomeBase{ public function index(){ $name='test'; return action('Posts/index',[$name]);//核心代码① } }
而在thinkphp6中框架取消了助手函数action,那是不是就不能直接利用框架自带的工具来完成这样的需求呢?答案肯定是否定的,实际上thinkphp还有两个常用的助手函数可以实现这样的需求,那就是invoke和app。
1、invoke
invoke用于调用反射执行callable,支持依赖注入,方法代码如下:
/** * 调用反射实例化对象或者执行方法 支持依赖注入 * @param mixed $call 类名或者callable * @param array $args 参数 * @return mixed */ function invoke($call, array $args = []) { if (is_callable($call)) { return Container::getInstance()->invoke($call, $args); } return Container::getInstance()->invokeClass($call, $args); }
实现上述需求的示例代码(把上面示例中的核心代码①修改)如下:
return invoke(['app\home\controller\Posts','index'],[$name]);
2、app
invoke用于快速获取容器中的实例,支持依赖注入,方法代码如下:
/** * 快速获取容器中的实例 支持依赖注入 * @param string $name 类名或标识 默认获取当前应用实例 * @param array $args 参数 * @param bool $newInstance 是否每次创建新的实例 * @return object|App */ function app(string $name = '', array $args = [], bool $newInstance = false) { return Container::getInstance()->make($name ?: App::class, $args, $newInstance); }
实现上述需求的示例代码(把上面示例中的核心代码①修改)如下:
return app('app\home\controller\Posts',[$name])->index();
也可以把参数放在后面
return app('app\home\controller\Posts')->index($name);
这样我们就使用invoke或app代替action实现调用控制器方法,关于invoke和app助手函数的具体用法大家可以详细阅读thinkphp官方文档的详细说明。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流