vertigolabs / mandate
运行一系列命令
Requires (Dev)
- satooshi/php-coveralls: dev-master
This package is auto-updated.
Last update: 2024-09-05 18:43:58 UTC
README
一个支持命令优先级、命令链、每个命令多个处理程序和工件的任务队列
Mandate 非常简单易用。
用法
文件
以下是在示例中将要使用的所有文件
NumberCommand.php
<?php use VertigoLabs\Mandate\Command; class NumberCommand extends Command { protected $number; public function __construct($number) { $this->number = $number; } }
*AddTwoHandler.php
<?php use VertigoLabs\Mandate\Command; use VertigoLabs\Mandate\Handler; class AddTwoHandler extends Handler { public function handle(Command $command) { if (!is_numeric($command->number)) { throw new \InvalidArgumentException('Number must be numeric'); } // we'll just var_dump to get output.. as you should not return data from a handler var_dump($command->number + 2); return true; } }
一个非常基础的例子
用法
按顺序运行命令
$mandate = new \VertigoLabs\Mandate\Mandate(); $addTwoHandler = new AddTwoHandler(); $command1 = new NumberCommand(1); $command1->addHandler($addTwoHandler); $command2 = new NumberCommand(2); $command2->addHandler($addTwoHandler); $mandate->queue($command1) ->queue($command2) ->execute();
这将产生以下输出
int(3)
int(4)
按优先级运行命令
优先级越高,运行越快
$mandate = new \VertigoLabs\Mandate\Mandate(); $addTwoHandler = new AddTwoHandler(); $command1 = new NumberCommand(1); $command1->addHandler($addTwoHandler); $command2 = new NumberCommand(2); $command2->addHandler($addTwoHandler); $command3 = new NumberCommand(4); $command3->addHandler($addTwoHandler); $mandate->queue($command1,1) ->queue($command2,4) ->queue($command3,2) ->execute();
这将产生以下输出
int(4)
int(6)
int(3)
注意运行顺序是 $command2, $command3, $command1
重用命令
您甚至可以多次重新发布一个命令:优先级越高,运行越快
$mandate = new \VertigoLabs\Mandate\Mandate(); $addTwoHandler = new AddTwoHandler(); $command1 = new NumberCommand(1); $command1->addHandler($addTwoHandler); $command2 = new NumberCommand(2); $command2->addHandler($addTwoHandler); $command3 = new NumberCommand(4); $command3->addHandler($addTwoHandler); $mandate->queue($command1,1) ->queue($command2,4) ->queue($command3,2) ->queue($command2,7) ->queue($command2,0) ->execute();
这将产生以下输出
int(4)
int(4)
int(6)
int(3)
int(4)
命令回调
用法
命令可以在成功执行或失败时运行回调函数
闭包作为回调
$command1 = new NumberCommand(1); $command1->onSuccess( function(){ echo "Command 1 completed successfully!"; } );
$command1 = new NumberCommand(1); $command1->onFailure( function(){ echo "Oops! I failed :("; } );
方法作为回调
$command1 = new NumberCommand(1); $command1->onSuccess(['myObject','myMethod']) ->onFailure(['otherObject','anotherMethod']);
工件
工件仍然是实验性的
传统上,命令/处理程序模式不允许返回值,至少我看到的大多数都不允许,如果我有误,请纠正我。无论如何,Mandate 在“返回数据”方面采取了一种完全不同的方法。
Mandate 使用 工件。工件基本上是从处理程序返回的数据。处理程序会 发出 工件。处理程序可以发出多个工件。每个工件都有一个名称,以便可以访问。
简单工件使用
对于这个例子,您需要另一个处理程序文件
addThreeHandler.php
<?php use VertigoLabs\Mandate\Command; use VertigoLabs\Mandate\Handler; class AddThreeHandler extends Handler { public function handle(Command $command) { if (!is_numeric($command->number)) { throw new \InvalidArgumentException('Number must be numeric'); } $sum3 = $command->number + 3; var_dump($sum3); $this->emitArtifact('sum3', $sum3); return true; } }
为了允许处理程序发出工件,它应该被“注册”到处理程序的实例中。这是故意的,这样开发者可以在不深入查看处理程序的情况下看到工件已被注册。
$mandate = new \VertigoLabs\Mandate\Mandate(); // set up the handler $addThreeHandler = new AddThreeHandler(); $addThreeHandler->produceArtifact('sum3'); // set up the command $command = new NumberCommand(1); $command->addHandler($addThreeHandler); $mandate->queue($command)->execute(); var_dump($addThreeHandler->getArtifacts('sum3'));
这将产生以下输出
int(4) // remember the handler has a var_dump also...
int(4)
复杂工件使用
工件的力量在更复杂的情况下使用时才显现出来。
将工件绑定到命令上
假设您有一个依赖于另一个命令/处理程序输出的命令。在这种情况下,您可以绑定工件到命令!
$mandate = new \VertigoLabs\Mandate\Mandate(); // setup the handler $addThreeHandler = new AddThreeHandler(); $addThreeHandler->produceArtifact('sum3'); // setup the commands $command1 = new NumberCommand(1); $command->addHandler($addThreeHandler); // here we set up our second command to receive the "sum3" artifact // we'll insert null into the command's constructor since that value is // the result of command1 being performed by the handler $command2 = new NumberCommand(null); $command2->addHandler($addThreeHandler); // notice the first parameter is the name of the constructor's parameter // the second parameter is the name of the artifact $command2->bindArtifact('number','sum3'); $mandate->queue($command1) ->queue($command2) ->execute();
这将产生以下输出
int(4)
int(7) // because the result of $command1 is 4, so we added 3!
当发出具有相同名称的新工件时,工件将被覆盖
$mandate = new \VertigoLabs\Mandate\Mandate(); // setup the handler $addThreeHandler = new AddThreeHandler(); $addThreeHandler->produceArtifact('sum3'); // setup the commands $command1 = new NumberCommand(1); $command->addHandler($addThreeHandler); $command2 = new NumberCommand(null); $command2->addHandler($addThreeHandler); $command2->bindArtifact('number','sum3'); $command3 = new NumberCommand(null); $command3->addHandler($addThreeHandler); $command3->bindArtifact('number','sum3'); $mandate->queue($command1) ->queue($command2) ->queue($command3) ->execute();
这将产生以下输出
int(4) // the artifact "sum3" is set to 4 at this point
int(7) // the artifact "sum3" is updated to 7 at this point
int(10) // the artifact "sum3" is updated to 10 at this point
等待工件可用
有时工件在运行命令时并不立即可用。对于这种情况,您可以指示命令等待工件可用。
当命令被指示等待工件时,它将自动重新排队到下一个较低优先级级别
$mandate = new \VertigoLabs\Mandate\Mandate(); // setup the handlers // remember AddTwoHandler does not produce artifacts $addTwoHandler = new AddTwoHandler(); $addThreeHandler = new AddThreeHandler(); $addThreeHandler->produceArtifact('sum3'); // setup the commands $command1 = new NumberCommand(null); $command1->addHandler($addTwoHandler); $command1->bindArtifact('number','sum3', true); $command2 = new NumberCommand(2); $command2->addHandler($addThreeHandler); $command3 = new NumberCommand(null); $command3->addHandler($addThreeHandler); $command3->bindArtifact('number','sum3'); $mandate->queue($command1) ->queue($command2) ->queue($command3) ->execute();
这将产生以下输出
// the "sum3" artifact is not found, requeued $command1
// $command2 is ran and produces "sum3" with a value of 5
int(5)
// now "sum3" is available so command 1 runs
int(7)
// at this point, "sum3" is still available with a value of 5
int(8)
// the artifact "sum3" still exists, however with a value of 8
等待工件的命令将不断重新排队,直到工件可用。当所有可能的命令都耗尽且工件从未产生时,将抛出异常以通知您工件从未找到。