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 相关文章推荐
如何在WIN2K下安装PHP4.04
Oct 09 PHP
Zend的AutoLoad机制介绍
Sep 27 PHP
smarty获得当前url的方法分享
Feb 14 PHP
一个不易被发现的PHP后门代码解析
Jul 05 PHP
php防止网站被刷新的方法汇总
Dec 01 PHP
PHP利用APC模块实现大文件上传进度条的方法
Oct 29 PHP
CodeIgniter多语言实现方法详解
Jan 20 PHP
PHP单例模式是什么 php实现单例模式的方法
May 14 PHP
CentOS 7.2 下编译安装PHP7.0.10+MySQL5.7.14+Nginx1.10.1的方法详解(mini版本)
Sep 01 PHP
PHP静态成员变量和非静态成员变量详解
Feb 14 PHP
PHP获取本周所有日期或者最近七天所有日期的方法
Jun 20 PHP
浅析PHP7的多进程及实例源码
Apr 14 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/04/01 PHP
让ThinkPHP支持大小写url地址访问的方法
2014/10/31 PHP
PHP实现懒加载的方法
2015/03/07 PHP
ZF框架实现发送邮件的方法
2015/12/03 PHP
php版微信发红包接口用法示例
2016/09/23 PHP
PHP 实现人民币小写转换成大写的方法及大小写转换函数
2017/11/17 PHP
CL vs ForZe BO5 第二场 2.13
2021/03/10 DOTA
推荐10个2014年最佳的jQuery视频插件
2014/11/12 Javascript
jQuery实现的经典滑动门效果
2015/09/22 Javascript
js获取当前年月日-YYYYmmDD格式的实现代码
2016/06/01 Javascript
AngularJS使用angular.bootstrap完成模块手动加载的方法分析
2017/01/19 Javascript
微信小程序技巧之show内容展示,上传文件编码问题
2017/01/23 Javascript
Bootstrap模态框插件使用详解
2017/05/11 Javascript
JS实现快速比较两个字符串中包含有相同数字的方法
2017/09/11 Javascript
浅析Javascript中双等号(==)隐性转换机制
2017/10/27 Javascript
swiper移动端轮播插件(触碰图片之后停止轮播)
2017/12/28 Javascript
浅析前端路由简介以及vue-router实现原理
2018/06/01 Javascript
angularJs中$scope数据序列化的实例
2018/09/30 Javascript
vue2 v-model/v-text 中使用过滤器的方法示例
2019/05/09 Javascript
微信公众号生成新浪短网址的实现(快速生成)
2019/08/18 Javascript
react用Redux中央仓库实现一个todolist
2019/09/29 Javascript
详解微信小程序之提高应用速度小技巧
2020/01/07 Javascript
vue 实现动态路由的方法
2020/07/06 Javascript
[00:57]英雄,你的补给到了!
2020/11/13 DOTA
解决每次打开pycharm直接进入项目的问题
2018/10/28 Python
浅谈python图片处理Image和skimage的区别
2019/08/04 Python
python中如何进行连乘计算
2020/05/28 Python
django models里数据表插入数据id自增操作
2020/07/15 Python
详解CSS3 rem(设置字体大小) 教程
2017/11/21 HTML / CSS
Currentbody西班牙:美容仪专家
2019/09/28 全球购物
MYSQL支持事务吗
2013/08/09 面试题
个人生活学习自我评价范文
2013/11/26 职场文书
生物工程专业求职信
2014/09/03 职场文书
2014党员四风对照检查材料思想汇报
2014/09/17 职场文书
解决pytorch读取自制数据集出现过的问题
2021/05/31 Python
 Redis 串行生成顺序编码的方法实现
2022/04/03 Redis