alchemy / binary-driver
构建二进制驱动程序的工具集
Requires
- php: >=5.5
- evenement/evenement: ^3.0|^2.0|^1.0
- psr/log: ^1.0
- symfony/process: ^2.3|^3.0|^4.0|^5.0
Requires (Dev)
- phpunit/phpunit: ^4.0|^5.0
README
Binary-Driver 是一组 PHP 工具,用于构建二进制驱动程序。
为什么?
你可能想知道,为什么我要构建一个库,而不是使用 exec
或 symfony/process?
这里有一个简单的答案
-
如果你使用
exec
、passthru
、system
、proc_open
或 PHP 中的任何低级进程处理,你应该看看 symfony/process 组件,该组件将提供一个面向对象、可移植、可测试和安全的接口来处理这些。乍一看这似乎很简单,但如果你看看这个组件的 单元测试,你会发现使用简单接口处理进程很容易变成一场噩梦。 -
如果你已经使用 symfony/process,并且想要构建二进制驱动程序,你将始终有一个相同的常用方法集和对象来配置、记录、调试和生成进程。这个库是实现任何具有这些常用需求的二进制驱动程序的基础。
AbstractBinary
AbstractBinary
提供了一个抽象类来构建二进制驱动程序。它实现了 BinaryInterface
。
实现示例
use Alchemy\BinaryDriver\AbstractBinary; class LsDriver extends AbstractBinary { public function getName() { return 'ls driver'; } } $parser = new LsParser(); $driver = Driver::load('ls'); // will return the output of `ls -a -l` $parser->parse($driver->command(array('-a', '-l')));
二进制检测故障排除
如果你使用 Nginx 与 PHP-fpm,由于 $_ENV['path']
为空,可执行文件检测可能不会正常工作。为了避免有空的 PATH
环境变量,请将以下行添加到你的 fastcgi_params
配置文件中(将 /your/current/path/
替换为 printenv PATH
的输出)
fastcgi_param PATH /your/current/path
记录
你可以通过将 Psr\Log\LoggerInterface
作为加载方法的第二个参数传入来使用 Psr\Log\LoggerInterface
记录事件。
$logger = new Monolog\Logger('driver'); $driver = Driver::load('ls', $logger);
监听器
你可以在进程中添加自定义监听器。监听器建立在 Evenement 之上,必须实现 Alchemy\BinaryDriver\ListenerInterface
。
use Symfony\Component\Process\Process; class DebugListener extends EventEmitter implements ListenerInterface { public function handle($type, $data) { foreach (explode(PHP_EOL, $data) as $line) { $this->emit($type === Process::ERR ? 'error' : 'out', array($line)); } } public function forwardedEvents() { // forward 'error' events to the BinaryInterface return array('error'); } } $listener = new DebugListener(); $driver = CustomImplementation::load('php'); // adds listener $driver->listen($listener); $driver->on('error', function ($line) { echo '[ERROR] ' . $line . PHP_EOL; }); // removes listener $driver->unlisten($listener);
捆绑的监听器
调试监听器是一个简单的监听器,用于捕获 stderr
和 stdout
输出;阅读实现以进行自定义。
use Alchemy\BinaryDriver\Listeners\DebugListener; $driver = CustomImplementation::load('php'); $driver->listen(new DebugListener()); $driver->on('debug', function ($line) { echo $line; });
ProcessBuilderFactory
ProcessBuilderFactory 通过生成 Symfony [Process] 对象(https://symfony.ac.cn/doc/master/components/process.html)来简化进程的启动。
use Alchemy\BinaryDriver\ProcessBuilderFactory; $factory = new ProcessBuilderFactory('/usr/bin/php'); // return a Symfony\Component\Process\Process $process = $factory->create('-v'); // echoes '/usr/bin/php' '-v' echo $process->getCommandLine(); $process = $factory->create(array('-r', 'echo "Hello !";')); // echoes '/usr/bin/php' '-r' 'echo "Hello !";' echo $process->getCommandLine();
配置
一个简单的配置对象,提供 ArrayAccess
和 IteratorAggregate
接口。
use Alchemy\BinaryDriver\Configuration; $conf = new Configuration(array('timeout' => 0)); echo $conf->get('timeout'); if ($conf->has('param')) { $conf->remove('param'); } $conf->set('timeout', 20); $conf->all();
使用 ArrayAccess
接口相同的示例
use Alchemy\BinaryDriver\Configuration; $conf = new Configuration(array('timeout' => 0)); echo $conf['timeout']; if (isset($conf['param'])) { unset($conf['param']); } $conf['timeout'] = 20;
许可
本项目根据 MIT 许可证发布。