brad-jones/superclosure

此包已被废弃且不再维护。没有建议的替代包。

使用序列化等方式处理闭包的有趣操作。

v2.0.0 2014-10-08 06:39 UTC

This package is not auto-updated.

Last update: 2017-03-22 04:00:35 UTC


README

Latest Stable Version Total Downloads Build Status GitTip

你见过这个吗?

未捕获异常 'Exception',消息为 '序列化 'Closure' 是不允许的'

这是真的!如果你尝试序列化一个 Closure,PHP 将抛出异常并告诉你这是不允许的。但是尽管它不被 PHP "允许",Super Closure 库(在 Packagist 上的 jeremeamia/superclosure)让它成为可能。

我不是开玩笑,你真的可以序列化 PHP 闭包

require 'vendor/autoload.php';

use Jeremeamia\SuperClosure\SerializableClosure;

$greeting = 'Hello';
$helloWorld = new SerializableClosure(function ($name = 'World') use ($greeting) {
    echo "{$greeting}, {$name}!\n";
});

$helloWorld();
//> Hello, World!
$helloWorld('Jeremy');
//> Hello, Jeremy!

$serialized = serialize($helloWorld);
$unserialized = unserialize($serialized);

$unserialized();
//> Hello, World!
$unserialized('Jeremy');
//> Hello, Jeremy!

是的,很酷吧?

了解更多!

这一切始于2010年初,当时PHP 5.3开始流行起来。我在前雇主的博客HTMList上发表了一篇名为使用序列化和反射扩展PHP 5.3闭包的文章,展示了如何实现。从那时起,我对代码进行了一些迭代,这个最新的迭代带来了一个更稳健的解决方案,它利用了nikic/php-parser库。

功能

  • 允许序列化闭包
  • 处理使用/继承/导入变量的闭包
  • 处理使用其他闭包的闭包
  • 处理参数或体中引用类名的闭包
  • 处理递归闭包(仅限PHP 5.4+)
  • 允许你获取闭包的代码
  • 允许你获取闭包使用的变量名和值
  • 允许你获取表示闭包代码的抽象语法树(AST)
  • 将魔法常量替换为其预期值,以便在反序列化后闭包按预期运行
  • 使用nikic/php-parser库通过精确的上下文无关文法解析方法
  • PSR-0兼容,可以通过Composer安装

注意事项

  1. 对于任何使用引用(例如,function () use (&$vars, &$like, &$these) {…})的变量,序列化和反序列化后引用不会保留。唯一的例外是(仅限PHP 5.4+),使用变量是序列化的 SerializableClosure 对象的引用,这是递归函数的情况。由于某种原因——我实际上并不完全理解——这行得通。
  2. 如果你在单行上定义了两个闭包(你本来就不应该这样做),你将无法序列化任何一个,因为不清楚应该解析哪个闭包的代码。
  3. 由于获取闭包代码和上下文的技术需要反射和完整的AST样式解析,序列化闭包的性能可能不佳。
  4. 警告:反序列化闭包需要 eval()extract()。许多人都认为这些函数很危险,所以你必须评估是否真的想使用这个库。这些函数必须使用才能使此技术工作。

安装

要使用Composer在项目中安装Super Closure库,首先请将以下内容添加到您的composer.json配置文件中。

{
    "require": {
        "jeremeamia/superclosure": "~1.0"
    }
}

然后运行Composer的安装或更新命令以完成安装。有关如何使用Composer的更多信息,请访问Composer主页

为什么我需要序列化闭包?

既然您正在查看这个README文件,您可能已经有了相应的用例。尽管这个概念最初只是一个实验,但在实际应用中已经出现了一些用例。

例如,在UserScape关于Laravel 4和IronMQ的视频中,大约在7:50的位置,他们展示了如何将闭包作为一个工作推送到队列中,以便由工作进程执行。这样做的好处是您不需要为可能非常简单的作业创建整个类。闭包序列化是由基于我较旧版本的SuperClosure的Laravel 4框架中的一个类完成的。

本质上,这个库允许您在一个进程中创建闭包并在另一个进程中使用它们。甚至可以通过API提供闭包(或算法)作为服务。

谁在使用Super Closure?

  • Laravel 4 - 序列化闭包以推送到作业队列。
  • PHP的HTTP Mock - 序列化闭包以在测试工作流程中发送到远程服务器。
  • Jumper - 序列化闭包以通过SSH在远程主机上运行。
  • nicmart/Benchmark - 使用ClosureParser显示基准测试的闭包代码。
  • 请告诉我您的项目是否以及如何使用Super Closure。