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下intval()和(int)转换使用与区别
Jul 18 PHP
安装apache2.2.22配置php5.4(具体操作步骤)
Jun 26 PHP
PHP与javascript实现变量交互的示例代码
Jul 23 PHP
php后台如何避免用户直接进入方法实例
Oct 15 PHP
php网站地图生成类示例
Jan 13 PHP
php利用cookies实现购物车的方法
Dec 10 PHP
反射调用private方法实践(php、java)
Dec 21 PHP
PHP pear安装配置教程
May 14 PHP
PHP 等比例缩放图片详解及实例代码
Sep 18 PHP
laravel-admin select框默认选中的方法
Oct 03 PHP
thinkPHP框架乐观锁和悲观锁实例分析
Oct 30 PHP
TP5框架安全机制实例分析
Apr 05 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获得用户使用的代理服务器ip即真实ip
2006/12/31 PHP
Mysql数据库操作类( 1127版,提供源码下载 )
2010/12/02 PHP
PHP中IP地址与整型数字互相转换详解
2014/08/20 PHP
PHP上传图片时判断上传文件是否为可用图片的方法
2016/10/20 PHP
js 数组实现一个类似ruby的迭代器
2009/10/27 Javascript
Jquery下的26个实用小技巧(jQuery tips, tricks &amp; solutions)
2010/03/01 Javascript
js控制页面控件隐藏显示的两种方法介绍
2013/10/09 Javascript
简单易用的倒计时js代码
2014/08/04 Javascript
了不起的node.js读书笔记之node的学习总结
2014/12/22 Javascript
JavaScript代码实现禁止右键、禁选择、禁粘贴、禁shift、禁ctrl、禁alt
2015/11/17 Javascript
JS/jQ实现免费获取手机验证码倒计时效果
2016/06/13 Javascript
bootstrap datepicker 与bootstrapValidator同时使用时选择日期后无法正常触发校验的解决思路
2016/09/28 Javascript
js, jQuery实现全选、反选功能
2017/03/08 Javascript
解决vue里碰到 $refs 的问题的方法
2017/07/13 Javascript
react-navigation 如何判断用户是否登录跳转到登录页的方法
2017/12/01 Javascript
JS把字符串格式的时间转换成几秒前、几分钟前、几小时前、几天前等格式
2019/07/10 Javascript
JavaScript面向对象程序设计中对象的定义和继承详解
2019/07/29 Javascript
layui form表单提交后实现自动刷新
2019/10/25 Javascript
动态实现element ui的el-table某列数据不同样式的示例
2021/01/22 Javascript
[03:56]显微镜下的DOTA2第十一期——鬼畜的死亡先知播音员
2014/06/23 DOTA
Python 的 with 语句详解
2014/06/13 Python
python编写暴力破解FTP密码小工具
2014/11/19 Python
Python实现的多线程端口扫描工具分享
2015/01/21 Python
python实现带声音的摩斯码翻译实现方法
2015/05/20 Python
在Mac OS系统上安装Python的Pillow库的教程
2015/11/20 Python
python学生管理系统代码实现
2020/04/05 Python
对python中url参数编码与解码的实例详解
2019/07/25 Python
解决Tensorflow2.0 tf.keras.Model.load_weights() 报错处理问题
2020/06/12 Python
python 利用jieba.analyse进行 关键词提取
2020/12/17 Python
详解CSS3开启硬件加速的使用和坑
2017/08/21 HTML / CSS
CSS3 实现飘动的云朵动画
2020/12/01 HTML / CSS
德国大型的家具商店:Pharao24.de
2016/10/02 全球购物
英国泰坦旅游网站:全球陪同游览,邮轮和铁路旅行
2016/11/29 全球购物
人力资源作业细则
2014/03/03 职场文书
大四学生个人总结
2015/02/15 职场文书
解决mysql:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO/YES)
2021/06/26 MySQL