aaronsaray/php-flow-control

此包已被废弃,不再维护。未建议替代包。

PHP的基本流程控制框架

1.0.0 2015-11-30 23:22 UTC

This package is auto-updated.

Last update: 2023-11-21 18:26:05 UTC


README

此库帮助在PHP中创建流程控制或流程。它实际上只是为在PHP中开发自己的工作流程提供框架。

安装说明

使用以下命令安装最新版本

$ composer require aaronsaray/php-flow-control

文档

入门

此处的目标是记住每个工作流程(点)只应了解下一个可能的场景。这些特定的点还没有反向构建。 :) 基于这个想法,使用此框架来创建PHP流程控制。

如果您将其视为向下一个步骤发展的树,这将有所帮助。对于“下一个”点,您可以有1-n个可能的结果。

点具有有效载荷,用于确定要采取行动的对象。这可能是一个从数据库检索的对象(想象一个用户构建的系统,该系统处理用户确定的流程),或者是一个用于在控制器中处理重定向请求的单个URL。

示例

在这个特定的例子中,我们将创建一个多步向导。我们知道步骤的当前顺序,但业务规则有时会变化。有时某些步骤必须首先发生 - 其他时候我们正在更新的对象可能具有不同的属性,这些属性是必需的。

在这个例子中,我们将有三个步骤

  • 你叫什么名字? - 在/问题/名字处询问
  • 你多大了? - 在/问题/old?id=question_id处询问
  • 你喜欢蛋糕吗? - 在/do-you-like-cake?id=question_id处询问

最后,我们将在/your/results/are/here/question_id处看到结果

class Payload implements PayloadInterface
{
  protected $url;
  
  public function __construct($url)
  {
    $this->url = $url;
  }
  
  public function get()
  {
    return $this->url;
  }
}

此有效载荷是一个非常简单的对象。它所做的一切就是传递一个单一的字符串url。这个有效载荷可以非常高级,基于您的业务规则。此对象不仅限于仅与字符串一起工作 - 它可以返回一个新的整个对象,甚至可以决定应用程序跳转到不同的流程。

class Director extends DirectorAbstract
{
  public function getFirstAllowed()
  {
    $this->setPoint(new Point\WhatsYourName());
    return $this->getPoint();
  }
}

每个工作流程由点和导演组成。导演的主要工作是指出工作流程的开始,就像这个例子一样。其余的功能在抽象中。在这种情况下,我们的流程的第一步是这个点。

class Question implements ProcessableInterface
{
  public $id;
  public $name;
  public $age;
  public $cake;
}

这是一个我们正在跟踪的对象。非常复杂,我知道...

class WhatsYourName extends PointAbstract
{
  public function getPayload()
  {
    return new Payload('/question/name');
  }
  
  public function next(ProcessableInterface $question)
  {
    if (empty($question->name)) throw new IllegalPointException();
    
    return new WhatsYourAge($question);
  }
}

您从这里开始可以看到工作流程的强大功能。get payload创建了一个表示当前状态的payload对象。在我们的例子中,我们的状态是URL引用 - 因此这是此特定点的URL。

next()方法调用传递了问题对象。从那里,它执行业务逻辑以确定是否可以转到下一个点(或问题)。如果没有业务验证的必要,您可以简单地返回下一个点。在这种情况下,我们不希望在下一个点(年龄)询问之前有名字。我们假设在此次调用运行期间,某个地方已分配了一个名字给问题。

class WhatsYourAge extends PointAbstract
{
  protected $question;
  
  public function __construct($question) 
  {
    $this->question = $question;
  }
  
  public function getPayload()
  {
    return new Payload('/question/age?id=' . $this->question->id);
  }
  
  public function next(ProcessableInterface $question)
  {
    if (empty($question->age)) throw new IllegalPointException();
    
    return new YaLikeCake($this->question);
  }
}

这里您可以看到有效载荷如何可能被特定的可处理对象改变的一个示例。

从这里开始,其余的对象看起来都一样——除非是结束树/工作流程的点。这个点不需要有next()方法——因为它应该只抛出异常来指示没有更多的点。(抽象类已经做到了这一点)。

那么,接下来,在我们的例子中,让我们开始请求。我们想要获取第一个点并将其放入链接中。

$director = new Director();
$url = $director->getFirstAllowed()->getPayload()->get();
echo "<a href='{$url}'>Begin the questions!</a>";

想象一个场景,用户可能从工作流程中退出——但他们应该能够再次选择?你可以调用getLastAllowed()方法来获取他们可能访问的最后一个。例如,如果用户回答了他们的名字和年龄,以下示例将返回基于我们示例的/do-you-like-cake?id=question_id链接。

$question = retrieveQuestionFromSomePreviousState();
$director = new Director();
$url = $director->getLastAllowed($question)->getPayload()->get();
echo "<a href='{$url}'>Finish up the questions!</a>";

在各个步骤中,你需要与点交互。想象一下名字问题成功提交后的场景

$question = new Question();
$question->name = $_POST['name'];
$director = new Director();
$nextUrl = $director->getNextPoint()->getPayload()->get();
die(header("Location: {$nextUrl}"));

这允许你的控制器理解它应该分配值或执行任何其他控制器逻辑,但并不一定需要知道它将把工作流程发送到下一个位置。

关于

我再次创建了一个多步骤的应用程序——一个基于向导的系统——我一直在想,我这样做很多次,我希望有更简单的方法来做这件事。当步骤/步骤顺序发生变化时,情况变得更糟。我决定创建这个脚手架,作为开发您自己的PHP流程或工作流程控制的方式。

要求

  • PHP 5.3+

错误和功能请求

错误和功能请求在GitHub上跟踪

作者

Aaron Saray - http://aaronsaray.com

许可证

此库根据MIT许可证授权——有关详细信息,请参阅LICENSE文件

致谢

我们在https://www.smallshopsunited.com的工作中使用此流程控制器——请访问并查看。