liyuze/method-chaining-proxy
Composer 安装命令:
composer require liyuze/method-chaining-proxy
包简介
通过代理方式实现方法链式调用,消除控制语句对链式的影响。
README 文档
README
流式接口(fluent interface)是软件工程中面向对象API的一种实现方式,以提供更为可读的源代码。方法链式调用(method chaining)是流式接口的一种实现。
在 PHP 中的实现方式是在类的方法返回值中返回 $this 或 new static() 来实现方法链式调用。
本扩展包尝试解决:
- 传统返回值(无
return或有return的值非本类对象)下实现链式调用。 - 通过"强制"忽略(tap 模式)或关注(pipe 模式)返回值实现更加灵活的链式调用。
- 优化控制语句(if/switch/foreach/while)对链式调用在代码层级中断。
关于代码提示:PHPStorm 暂不支持在@template 时同时使用 @mixin 语句 ,所以无法实现代码自动提示功能。如果你有更好实现代码提示的方法,欢迎与我联系~😃 !!!过度使用本包可能影响代码的可读性和增加程序调试难度,建议在简单的逻辑中使用。
灵感
灵感来源于 laravel 的 tap 和 pipe 方法。
/** * Call the given Closure with the given value then return the value. * * @param mixed $value * @param callable|null $callback * @return mixed */ function tap($value, $callback = null) { if (is_null($callback)) { return new HigherOrderTapProxy($value); } $callback($value); return $value; }
namespace Illuminate\Support\Traits; trait EnumeratesValues { ... /** * Pass the collection to the given callback and return the result. * * @param callable $callback * @return mixed */ public function pipe(callable $callback) { return $callback($this); } ... }
安装
你可以通过 composer 进行安装:
composer require liyuze/method-chaining-proxy
用例
快速创建代理器
mixed 代理器
创建代理器
$cat = new Cat('Tom', 5); $proxy = MethodChainingFactory::create($cat); //或 $proxy = MethodChainingFactory::mixed($cat);
默认创建的是 mixedMode 的代理器,特点是如果调用的方法**没有返回值或返回值是null**时不会更新代理器的代理值。
$proxy = $proxy->setAge(9)->setName('Tony')->getName(); $proxy->popValue(); //Tony $cat->getName(); //Tony
tap 模式代理器
也可以通过 tapMode() 方法创建一个忽略任何返回值,代理器值一直不变的值代理器。
$cat = new Cat('Tom', 5); $proxy = MethodChainingFactory::tap($cat); $proxy = $proxy->setAge(9)->setName('Tony')->getName(); $proxy->popValue(); //Cat('Tony', 9) $cat->getName(); //Tony
pipe 模式代理器
也可以通过 pipeMode() 方法创建一个接受任何返回值代理器。
$cat = new Cat('Tom', 5); $proxy = MethodChainingFactory::pipe($cat); $proxy = $proxy->setAge(9); $proxy->popValue(); //null $cat->getName(); //Tony
切换代理器模式
可以通过 'switchMixedMode()'、'switchTapMode()'、'switchPipeMode()' 方法来切换代理器的代理模式。
$cat = new Cat('Tom', 5); $proxy = MethodChainingFactory::tap($cat); $proxy = $proxy->switchToPipeMode()->getName();; $proxy->popValue(); //Tom $cat->getName(); //Tom
可以使用
mixed、tap、pipe属性访问方式来调用对应的切换代理方法。
如果临时切换代理模式的情况,可以通过'tapOnce()'、'pipeOnce()'制定,所制定的调用方法仅会生效一次。
$cat = new Cat('Tom', 5); $proxy = MethodChainingFactory::tap($cat); $proxy = $proxy->pipeOnce()->getName() $proxy->popValue(); //Tom $cat->getName(); //Tom
可以使用
tapOnce、pipeOnce属性访问方式来调用对应的单次切换代理方法。
摘取
可以通过 pick() 方法在方法链式调用过程中通过引用传值的方法获取某个属性值。
$cat = new Cat('Tom', 5); $name = null; $proxy = MethodChainingFactory::create($cat); $proxy->setAge(9)->pick('name', $name)->setName('Tony'); $name; //Tom $cat->getName(); //Tony
对于方法的值,可以通过 methodPick() 来摘取。
$cat = new Cat('Tom', 5); $name = null; $proxy = MethodChainingFactory::create($cat); $proxy = $proxy->setAge(9)->methodPick($name, 'getName')->setName('Tony');; $name; //Tom $cat->getName(); //Tony
后置操作
通过调用 after() 方法传入一个闭包来执行自定义的代码功能,它也支持链式调用。
闭包的第一个参数是当前代理器 代理值,如果闭包有返回值且不为null时将会更新代理器的代理值。
$cat = new Cat('Tom', 5); $birthMonth = 3; $proxy = MethodChainingFactory::create($cat); $proxy = $proxy->setAge(9)->setName('Tony')->after( function ($proxyValue) use ($birthMonth) { //6月前出生的加1岁 if ($birthMonth < 6) { $proxyValue->setAge($proxyValue->getAge() + 1); } });//->after(...)->after(...); $proxy->popValue()->getAge(); // 10 $number = MethodChainingFactory::create($cat)->after(fn () => 3)->popValue(); // 3
If 逻辑代理器
当给定的判定值为真时才会运行后续方法链的代理器。
$ifProxy = ControlChainingFactory::if(new Cat('Tom', 5), false); // 或 $ifProxy = new IfChainingProxy(new Cat('Tom', 5), false); $ifProxy->setName('Tony') ->elseChaining() ->setName('Alan'); $ifProxy->endSwitchChaining()->getName(); //Alan
也可以通过 ControlChainingFactory::unless() 创建一个判定值为假时才会运行后续方法链的代理器。
Switch 逻辑代理器
当给定的判定值与 caseChaining() 传入的值相等时才会运行后续方法链的代理器。
$switchProxy = ControlChainingFactory::switch(new Cat('Tom', 5), 2); // 或 $switchProxy = new SwitchChainingProxy(new Cat('Tom', 5), 2); $cat = $switchProxy ->caseChaining(1)->setName('Tony') ->caseChaining(2)->setName('Alan') ->endSwitchChaining(); $cat->getName(); //Alan $cat->getAge(); //10
通过 breakChaining() 中断以后代码的执行。
breakChaining(2)方法支持传入要中断的循环层级数量,中断效果只针对MethodChainingProxy类嵌套有效,不兼容原生的控制语句。
$switchProxy = ControlChainingFactory::switch(new Cat('Tom', 5), 2); // 或 $switchProxy = new SwitchChainingProxy(new Cat('Tom', 5), 2); $cat = $switchProxy ->caseChaining(1)->setName('Tony')->breakChaining() ->caseChaining(2)->setName('Alan') ->caseChaining(2)->setAge(10)->breakChaining() ->caseChaining(2)->setName('Andy') ->endSwitchChaining(); $cat->getName(); //Alan $cat->getAge(); //10
通过 `defaultChaining() 指定默认要执行的代码。
$switchProxy = ControlChainingFactory::switch(new Cat('Tom', 5), 2); // 或 $switchProxy = new SwitchChainingProxy(new Cat('Tom', 5), 2); $cat = $switchProxy ->caseChaining(1)->setName('Tony')->breakChaining() ->defaultChaining()->setName('Alan')->setAge(10) ->endSwitchChaining(); $cat->getName(); //Alan $cat->getAge(); //10
示例类
class Cat { public string $name; public int $age; public function __construct(string $name, int $age) { $this->name = $name; $this->age = $age; } public function getName() { return $this->name; } public function getAge() { return $this->age; } public function setName(string $name) { $this->name = $name; } public function setAge(int $age) { $this->age = $age; } public function setNameForChaining(string $name) { $this->name = $name; return $this; } public function setAgeForChaining(int $age) { $this->age = $age; return $this; } public function do(\Closure $closure) { $closure(); return $this; } }
测试
composer test
修改记录
点击 CHANGELOG 查看最近修改了哪些内容。
贡献
点击 CONTRIBUTING 查看详情
安全
如果您发现任何与安全相关的问题,请发送电子邮件290315384@qq.com而不是使用问题追踪器。
贡献值
开源协议
The MIT License (MIT)。点击 License File 查看更多信息。
PHP Package 模板
本扩展包使用 PHP Package Boilerplate 工具生成,该工具由 Beyond Code 提供。
liyuze/method-chaining-proxy 适用场景与选型建议
liyuze/method-chaining-proxy 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 10 次下载、GitHub Stars 达 0, 最近一次更新时间为 2022 年 05 月 04 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「php」 「method chaining」 「method chaining proxy」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 liyuze/method-chaining-proxy 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 liyuze/method-chaining-proxy 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 liyuze/method-chaining-proxy 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Trunkrs Shipping Method Plugin for Magento 2
paysafecard PHP REST API Library
A PHP utility class that creates a fluent interface for interacting with strings
A PHP helper utility class for fluent interaction and manipulation with collection data using immutable bags
An easy way to parse and manipulate identifier names, such as dynamic method names.
A PHP utility class that helps with common file tasks
统计信息
- 总下载量: 10
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 0
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2022-05-04