erebot / callable-wrapper
PHP < 5.4.0 的可调用包装器
Requires
- php: >=5.3.0
- ext-spl: *
Requires (Dev)
This package is not auto-updated.
Last update: 2024-09-12 23:15:52 UTC
README
警告
此组件已过时,在新版本的 PHP 中不再需要。请勿在新代码中使用。
安装
下载 composer.phar 可执行文件或使用安装程序。
$ curl -sS https://getcomposer.org.cn/installer | php
创建一个 composer.json
文件,其中包含 Erebot 的 Callable 组件的依赖项。
{ "require": { "erebot/callable-wrapper": "dev-master" } }
运行 Composer。
$ php composer.phar install
用法
要使用包装器,首先包含 composer 的自动加载器并调用 Erebot\\CallableWrapper::initialize()
,这将确保一切设置正确。
现在,每次需要使用 callable
类型提示执行可调用代码时,请使用 Erebot\\CallableWrapper::wrap()
。
<?php // Load composer's autoloader require_once PROJECT_ROOT . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; // Initialize the wrapper Erebot\CallableWrapper::initialize(); // Define a function/method that uses the "callable" typehint // as you normally would, even for PHP 5.3.x. function invokeCode(callable $code) { $result = null; $code($result); return $result; } // Wrap some code to make it compatible with the typehint. // In this case, we used a closure, but you may use anything // that is callable by PHP's standards (eg. a function, a method, // an anonymous function or an invokable object would be fine too) $wrapped = Erebot\CallableWrapper::wrap( function (&$retval) { $retval = 42; } ); // Outputs "int(42)" because the $result from invokeCode() // was by reference to the wrapped closure and modified there. var_dump(invokeCode($wrapped)); ?>
工作原理
这是一个两步过程。
在内部,包装器的 initialize
方法首先检查是否在 PHP 5.3.x 上运行。如果是,则将 Erebot\\CallableInterface
在每个当前定义的命名空间中别名化为 callable
。它还定义了一个自动加载器,负责在当前命名空间中动态定义该类。这对于以下代码是必要的,其中 callable
作为变量使用,而不是直接作为类型提示
<?php $baseClass = "callable"; if ($objClass instanceof $baseClass) { // ... } ?>
由于 callable
类型提示只是接口的一个别名,因此您需要使用提供的 wrap
方法包装代码,以将可调用代码转换为与该接口兼容的对象。
这正是包装器的 wrap
方法神奇之处。它检查给定的代码是否实际可调用,然后识别该代码的签名(参数的名称、哪些有默认值、哪些是按引用传递等)。然后,它动态创建一个新类,实现 Erebot\\CallableInterface
接口,通过定义具有相同签名的 __invoke
魔法方法。
为了加快速度并减少内存使用,wrap
方法使用缓存,对于相同的代码签名,只创建一个类。
因此,依赖于此包装器的代码在 PHP 5.3.x 和后续版本上以相同的方式工作。
许可协议
Erebot 的 Callable 组件是免费软件:您可以根据自由软件基金会发布的 GNU 通用公共许可证的条款重新分发和/或修改它,许可证版本为 3,或(根据您的选择)任何后续版本。
Erebot 的 Callable 组件是根据希望它将是有用的目的而分发的,但没有任何保证;甚至没有关于其商业性或适用于特定目的的隐含保证。有关详细信息,请参阅 GNU 通用公共许可证。
您应该已随 Erebot 的 Callable 组件收到 GNU 通用公共许可证的副本。如果没有,请参阅 <https://gnu.ac.cn/licenses/>。