PHP链式调用中保存Apple()结果并返回Banana()的实现问题
解答
PHP原生支持实现这类逻辑,你当前代码不生效的核心原因有两个:
getFruit()直接返回了Banana()的数组类型结果,非对象值无法调用后续的Apple()成员方法,会直接触发致命错误,中断执行。- 未在链式调用流程中捕获
Apple()的输出存入$keep,提前返回非对象值破坏了链式调用的必要条件。
核心逻辑说明
PHP链式调用的基础要求是:参与链式调用的中间方法必须返回当前类的对象实例,才能让后续的成员方法被正常调用。针对你的需求,只需要调整方法返回逻辑:让getFruit()返回类实例保证链式调用可继续,在Apple()方法内完成结果留存,最终返回Banana()的结果即可。
修正后可直接运行的代码
class Fruits { public static $keep; public static function getFruit() { // 返回当前类实例,为后续链式调用提供对象上下文 return new self(); } public function Apple() { // 将Apple方法的输出存入静态属性$keep self::$keep = ['func' => 'Apple', 'output' => 'An apple']; // 不返回Apple的执行结果,直接返回Banana方法的结果 return $this->Banana(); } public function Banana() { return ['func' => 'Banana', 'output' => 'A Banana']; } } // 原有调用代码不需要修改 $obj = Fruits::getFruit()->Apple(); echo '<pre>'; var_dump($obj); var_dump(Fruits::$keep); echo '</pre>';
运行结果
执行代码后会得到完全符合预期的效果:
Fruits::$keep存储Apple()方法的输出:array(2) { ["func"]=> string(5) "Apple" ["output"]=> string(8) "An apple" }$obj存储Banana()方法的输出:array(2) { ["func"]=> string(6) "Banana" ["output"]=> string(8) "A Banana" }
可选扩展方案
如果后续需要新增大量和Apple()逻辑一致的水果方法(调用后留存自身结果、最终返回Banana),可以通过__call魔术方法统一处理,无需为每个水果单独编写方法:
class Fruits { public static $keep; public static function getFruit() { return new self(); } // 捕获所有未定义的实例方法调用 public function __call($methodName, $args) { self::$keep = ['func' => $methodName, 'output' => 'An ' . strtolower($methodName)]; return $this->Banana(); } public function Banana() { return ['func' => 'Banana', 'output' => 'A Banana']; } }
该版本下直接调用Fruits::getFruit()->Orange()、Fruits::getFruit()->Pear()都可以实现相同逻辑,不需要额外编写对应方法。
内容的提问来源于stack exchange,提问作者WEB TM
相关产品推荐
相关产品推荐

