PHP实现基于状态的责任链审批模式详解


Posted in PHP onMay 31, 2019

本文实例讲述了PHP实现基于状态的责任链审批模式。分享给大家供大家参考,具体如下:

我们开发网站,除了前后,还有后台,除了内容管理,很多时候要涉及到『审批』。

比如:商务部要做个专题推广活动,活动中需要调用一些商品做优惠。

1、商务部编辑先写文案
2、商务部领导审批文案内容
3、商品部领导需要审批商品的价格和库存(万一没货呢)
4、后面可能还有好多领导要审批(带扩展)

今天我们要引入的模式是『责任链模式』

在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来,形成一条链条。请求在这个链条上传递,知道链条上的某一个对象决定处理次请求。发出这个请求的客户端并不知道链条上哪一个对象最终处理这个请求。

为了演示方便,我们做价格设定。

1、假定层级关系是:商品部领导>商务部领导>编辑
2、假设只能一级级审批(也就是不能跳级,仅为了演示方便)
3、这里审批暂时不能回退

PHP实现基于状态的责任链审批模式详解

(上图:演示界面show.php)

show.php:

<?php
  require('subject.php');
  if ($_GET){
    if (isset($_GET['createSubject'])){ //点击创建文案后执行
      $subject = new subject();
      $subject->content = '文案的内容';
      $subject->save();
    }
  }
?>
<html>
  <head>
    <title>责任链-审批</title>
    <style>
      *{marign:0;padding:0}
      .container{width:100%;margin: 0 auto;text-align: center}
    </style>
  </head>
  <body>
    <div class="container">
      <div><h2>流程演示界面</h2></div>
      <form method="get" action="show.php">
        <div class="row">
          <textarea name="" id="" cols="30" rows="10"></textarea>
          <div>
            <button name="createSubject">编辑创建文案</button>
          </div>
        </div>
        <div class="row">
          <hr>
          <button name="step">领导审批</button>
        </div>
      </form>
    </div>
  </body>
</html>

编辑点击『创建文案』提交内容,然后把文案写到到本地json文件(保存)。文案的主题是subject.php:

<?php
class subject
{
  public $content = ''; //文案内容
  public $state = 0; //初试状态
  /**
   * 保存内容(编辑保存)
   */
  public function save(){
    //我们这里保存到本地文件
    file_put_contents(__DIR__.'/subject.json',json_encode($this));
    echo '文案已经创建成功';
  }
}

这个时候文案已经创建好了,需要进入审批

抽象类(领导)manager.php :

<?php
abstract class manager
{
  public $subject; //加载专题内容
  public $mystate=0; //当前状态,这个很重要
  public $leader=false; //重要,设置自己的领导是谁
  public $myname = ''; //当前审批者的名字
  /**
   * 设置领导是谁
   * @param $leader
   */
  public function setLeader($leader)
  {
    $this->leader = $leader; //形成责任链的关键
  }
  public function __construct()
  {
    $str = file_get_contents(__DIR__.'/subject.json');
    $this->subject = json_decode($str);
  }
  public function step($msg)
  {
    //很重要,代表审批
    //只有当subject的state和自己的mystate相等是才会处理
    if ($this->subject->state == $this->mystate){ //代表当前是自己要处理的
      //在这执行审批通过的 具体
      echo $msg . '审批制是:'.$this->myname;
      //判断自己的是否有领导,如果有把控制权交给领导
      if ($this->leader){
        $this->subject->state = $this->leader->mystate; //交控制权
        file_put_contents(__DIR__.'/subject.json',json_encode($this->subject)); //保存状态
      }else{
        echo '审批已经结束';
      }
    }else{
      if ($this->leader){ //leader就是维护整个类的 链
        //让自己的领导去审批
        $this->leader->step($msg);
      }
    }
  }
}

商务部领导,商品部领导,大boss都要继承这个抽象类。

BusinessLeader.php

<?php
class BusinessLeader extends manager
{
  public $myname = '商务部领导';
  public $mystate = 0;
}

ProductLeader.php:

<?php
class ProductLeader extends manager
{
  public $myname = '商品部领导';
  public $mystate = 1;
}

LastLeader.php

<?php
class LastLeader extends manager
{
  public $myname = '终极领导';
  public $mystate = 2;
}

在编辑提交文案之后,会进入『领导审批』阶段:

if (isset($_GET['step'])){ //进入领导审批阶段了
  //这里面最关键是
   //1.确定第一个领导是谁
   //2. 要维护各个领导直接的关系,
   require ('manager.php');
   require ('BusinessLeader.php');
   require ('ProductLeader.php');
   require ('LastLeader.php');
   $businessLeader = new BusinessLeader();
   $productLeader = new ProductLeader();
   $lastLeader = new LastLeader();
   //下面还是维护关系
   $businessLeader->setLeader($productLeader);
   $productLeader->setLeader($lastLeader);
   $businessLeader->step('审批通过');
}

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP中用header图片地址 简单隐藏图片源地址
Apr 09 PHP
优化php效率,提高php性能的一些方法
Mar 24 PHP
PHP5中新增stdClass 内部保留类
Jun 13 PHP
PHP最常用的2种设计模式工厂模式和单例模式介绍
Aug 14 PHP
php实现插入数组但不影响原有顺序的方法
Mar 27 PHP
Symfony2学习笔记之控制器用法详解
Mar 17 PHP
php基于jquery的ajax技术传递json数据简单实例
Apr 15 PHP
php反射类ReflectionClass用法分析
May 12 PHP
php正则去除网页中所有的html,js,css,注释的实现方法
Nov 03 PHP
php+webSoket实现聊天室示例代码(附源码)
Feb 17 PHP
thinkPHP5.0框架独立配置与动态配置方法
Mar 17 PHP
PHP解析url并得到url参数方法总结
Oct 11 PHP
Laravel框架实现调用百度翻译API功能示例
May 30 #PHP
Laravel框架学习笔记之批量更新数据功能
May 30 #PHP
PHP实现的微信公众号扫码模拟登录功能示例
May 30 #PHP
PHP使用PDO创建MySQL数据库、表及插入多条数据操作示例
May 30 #PHP
TP5(thinkPHP5框架)基于bootstrap实现的单图上传插件用法示例
May 29 #PHP
TP5(thinkPHP框架)实现后台清除缓存功能示例
May 29 #PHP
PHP微信网页授权的配置文件操作分析
May 29 #PHP
You might like
php数组编码转换示例详解
2014/03/11 PHP
yii使用bootstrap分页样式的实例
2017/01/17 PHP
PHP获取文件扩展名的常用方法小结【五种方式】
2018/04/27 PHP
Laravel框架分页实现方法分析
2018/06/12 PHP
JQuery扩展插件Validate 2通过参数设置验证规则
2011/09/05 Javascript
js 获取class的元素的方法 以及创建方法getElementsByClassName
2013/03/11 Javascript
jQuery .attr()和.removeAttr()方法操作元素属性示例
2013/07/16 Javascript
js实现弹出窗口、页面变成灰色并不可操作的例子分享
2014/05/10 Javascript
在Google 地图上实现做的标记相连接
2015/01/05 Javascript
jQuery结合AJAX之在页面滚动时从服务器加载数据
2015/06/30 Javascript
JS添加删除DIV的简单实例
2016/07/08 Javascript
jquery 追加元素append、prepend、before、after用法与区别分析
2016/12/02 Javascript
Node.js中多进程模块Cluster的介绍与使用
2017/05/27 Javascript
vue2 中如何实现动态表单增删改查实例
2017/06/09 Javascript
vue element-ui 绑定@keyup事件无效的解决方法
2018/03/09 Javascript
在vue中安装使用vux的教程详解
2018/09/16 Javascript
关于微信小程序登录的那些事
2019/01/08 Javascript
vue 项目引入echarts 添加点击事件操作
2020/09/09 Javascript
Python中多线程thread与threading的实现方法
2014/08/18 Python
Python多线程编程(二):启动线程的两种方法
2015/04/05 Python
python使用Flask操作mysql实现登录功能
2018/05/14 Python
python3实现磁盘空间监控
2018/06/21 Python
对Python中list的倒序索引和切片实例讲解
2018/11/15 Python
python的debug实用工具 pdb详解
2019/07/12 Python
python解释器安装教程的方法步骤
2020/07/02 Python
使用Html5实现异步上传文件,支持跨域,带有上传进度条
2016/09/17 HTML / CSS
软件测试工程师面试问题精选
2016/10/28 面试题
信息工作经验交流材料
2014/05/28 职场文书
2014国庆节商场促销活动策划方案
2014/09/16 职场文书
2014年世界艾滋病日宣传活动总结
2014/11/18 职场文书
实习生辞职信范文
2015/03/02 职场文书
应届毕业生求职简历自我评价
2015/03/02 职场文书
同意离婚答辩状
2015/05/22 职场文书
科技馆观后感
2015/06/08 职场文书
详解Python描述符的工作原理
2021/06/11 Python
详解Java实现数据结构之并查集
2021/06/23 Java/Android