jgswift / delegatr
PHP 5.5+ 代理系统
0.1.6
2014-09-19 21:42 UTC
Requires
- php: >=5.5
- adlawson/veval: 1.*
- jeremeamia/functionparser: *
- jgswift/qtil: 0.1.*
Requires (Dev)
- phpunit/phpunit: 3.7.*
- satooshi/php-coveralls: dev-master
README
PHP 5.5+ 代理系统
安装
通过 CLI 使用 composer 安装
php composer.phar require jgswift/delegatr:0.1.*
通过 composer.json 使用 composer 安装
{
"require": {
"jgswift/delegatr": "0.1.*"
}
}
依赖项
- php 5.5+
- jgswift/FunctionParser - 从 jeremeamia/FunctionParser 分支
- adlawson/veval.php - 使用虚拟文件系统作为 eval 的后备
使用方法
内置 Lambda (具有可序列化)
PHP 中闭包的一个繁琐之处是需要显式使用 "use" 语句定义上下文变量。代理可以通过允许您指定一个关联数组来动态定义上下文,从而使这个过程更加痛苦。
$x = 10; $y = 2; $lambda = new delegatr\Lambda(function() { return $x + $y; }, get_defined_vars()); var_dump($lambda()); // 12
get_defined_vars 返回在同一个作用域中定义的变量列表(非引用),因此 $x 和 $y 在运行时动态添加到闭包的 "use" 语句中,并插入到闭包作用域中。
编写自定义可序列化闭包(使用 trait)
Delegatr 不仅将闭包封装在对象中,还使用 eval 来启用闭包的序列化 - 这是原生 PHP 无法做到的。
以下类使用可序列化代理来完成此操作。
class MyDelegate { use delegatr\Serializable; } $delegate = new MyDelegate(function() { return 'foo'; }); $serial_string = serialize($delegate); $delegate2 = unserialize($serial_string) var_dump($delegate2()); // returns 'foo';
使用上述 trait 可以防止 delegatr 对您的领域产生影响,但如果这不是问题,只需像下面所示实例化或继承 Lambda 类。
$delegate = new delegatr\Lambda(function() { return 'foo'; }); class MyLambda extends delegatr\Lambda { /* ... */ }
简单代理(没有序列化)
还提供了不带 \Serializable 的简单实现
class MyDelegate { use delegatr\Delegate; } $delegate = new MyDelegate(function() { return 'foo'; }); var_dump($delegate()); // returns 'foo';
Eval 后备 & 漏洞
该包大量依赖 eval 函数。
如果您不熟悉 eval 或不了解安全风险,我建议您不要使用此包。
然而,eval 本身并不需要此包。
Delegatr 使用 adlawson/veval.php 在禁用 eval 的环境中编译脚本,即使这样也不会减少代码注入的风险。