PHP如何直接用方法返回的字符串类名实例化对象?
如何直接链式实例化动态返回的类名
嘿,这个问题挺有意思的!虽然你说不会用到生产环境,但探索PHP的语法边界确实挺好玩的~
你遇到的语法错误,根源在于PHP解析器对new表达式的解析顺序:当你写new ($b->method($id))()时,解析器会优先把($b->method($id))()当成一个函数调用(试图把返回的类名字符串当作函数来执行),然后再对这个结果执行new操作,这显然不符合你的预期,自然会报错。
不过PHP确实支持直接通过表达式返回的类名来实例化对象,只需要调整一下语法即可:
正确的直接写法
// 如果构造函数不需要参数 $instance = new ($b->method($id)); // 如果构造函数需要参数,直接在后面加括号传参 $instance = new ($b->method($id))($param1, $param2);
这里的关键是用括号把$b->method($id)整个表达式包裹起来,告诉解析器先执行这个方法调用得到类名字符串,再用这个字符串作为类名进行实例化。
另一种更直观的写法(PHP 7+)
如果你觉得上面的括号有点绕,还可以用(new ...)的方式,写法更紧凑:
$instance = (new ($b->method($id)));
额外小技巧:用反射类实现
虽然没必要,但也可以用ReflectionClass来完成这个操作,逻辑更明确:
$instance = (new ReflectionClass($b->method($id)))->newInstance(); // 带参数的话用newInstanceArgs $instance = (new ReflectionClass($b->method($id)))->newInstanceArgs([$param1, $param2]);
总之,核心就是要明确告诉PHP解析器,先执行方法调用得到类名,再进行实例化操作,避免解析顺序导致的语法错误。
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

