Laravel能否为任意对象添加->when()或->unless()条件方法?
在Laravel中为任意对象添加
when()/unless()方法的实现方案 当然可以实现这个需求。Laravel的集合类本身自带when()和unless()方法,但要让任意类型的对象都支持这两个条件方法,你可以通过自定义一个对象包裹类来实现,同时完全保留原对象的所有功能。
具体实现步骤
1. 创建对象包裹类
在app/Support目录下创建ObjectWrapper.php:
<?php namespace App\Support; class ObjectWrapper { protected $object; public function __construct($object) { $this->object = $object; } // 实现when条件方法:条件为true时执行回调 public function when($condition, callable $callback) { if ($condition) { $result = $callback($this->object); // 若回调返回新对象,更新内部实例 if ($result !== null) { $this->object = $result; } } return $this; } // 实现unless条件方法:条件为false时执行回调 public function unless($condition, callable $callback) { return $this->when(!$condition, $callback); } // 魔术方法:转发所有未定义的方法调用到原对象 public function __call($method, $parameters) { $result = call_user_func_array([$this->object, $method], $parameters); // 若原方法返回自身(支持链式调用),返回包裹类保持链式 if ($result === $this->object) { return $this; } // 否则返回方法实际结果 return $result; } // 魔术方法:获取原对象属性 public function __get($property) { return $this->object->$property; } // 魔术方法:设置原对象属性 public function __set($property, $value) { $this->object->$property = $value; } // 提供方法获取原对象 public function unwrap() { return $this->object; } }
2. 创建全局wrap()辅助函数
在项目根目录创建app/helpers.php(如果已有则直接添加):
<?php if (!function_exists('wrap')) { function wrap($object) { return new \App\Support\ObjectWrapper($object); } }
然后更新Composer自动加载,让辅助函数生效:
composer dump-autoload
3. 使用示例
完全按照你期望的方式调用即可:
// 示例自定义对象 $myObject = new class { public function changeSomething() { // 执行修改逻辑 return $this; } public function doOtherAction() { // 执行其他操作 return $this; } }; // 包裹对象后链式调用 $object = wrap($myObject) ->when(true, function ($obj) { return $obj->changeSomething(); }) ->doOtherAction() // 直接调用原对象方法,不影响链式 ->unless(false, function ($obj) { return $obj->changeSomething(); }); // 如需获取原对象,调用unwrap() $originalObject = $object->unwrap();
关键说明
- 包裹类通过魔术方法实现了对原对象的完全转发,原对象的所有方法、属性都能正常使用。
when()/unless()方法支持回调返回新对象,包裹类会自动更新内部实例,保证链式调用的连贯性。- 这个实现完全兼容Laravel的生态,不会和框架现有功能冲突。
内容的提问来源于stack exchange,提问作者Pejman
相关产品推荐
相关产品推荐

