Skip to main content

钩子机制

1、钩子服务:common/components/HookManager.php

<?php
/**
 * Created by PhpStorm.
 * User: Lenovo
 * Date: 2025/9/18
 * Time: 18:55
 */

namespace common\components;


use common\tosan\Tools;

class HookManager extends \yii\base\Component
{
    private $_events = [];

    /**
     * 监听事件
     * @param string $event 事件名
     * @param callable $callback 回调函数
     * @param mixed $data 传递给回调函数的默认数据
     * @param bool $append 是否追加到监听队列的末尾
     */
    public function on($event, $callback, $data = null, $append = true)
    {
        if ($append || !isset($this->_events[$event])) {
            $this->_events[$event][] = [$callback, $data];
        } else {
            array_unshift($this->_events[$event], [$callback, $data]);
        }
    }

    /**
     * 触发事件
     * @param string $event 事件名
     * @param mixed $eventData 事件数据,会传递给回调函数
     * @return mixed 事件数据
     */
    public function trigger($event, $eventData = null)
    {
        if (!empty($this->_events[$event])) {
            foreach ($this->_events[$event] as $handler) {
                list($callback, $data) = $handler;
                // 将全局数据和事件数据合并,传递给回调函数
                if ($data === null) {
                    call_user_func($callback, $eventData);
                } else {
                    call_user_func($callback, $eventData, $data);
                }
            }
        }
        Tools::dump($event . '=>' . json_encode($eventData));
        switch ($event){
            case 'beforeReservation'://预约前
                break;
            case 'afterReservation'://预约后
                break;
            case 'beforeInbound'://入库前
                break;
            case 'afterInbound'://入库后
                break;
            case 'beforePutaway'://上架前
                break;
            case 'afterPutaway'://上架后
                break;
            case 'beforeCreateOrder'://创建出库单前
                break;
            case 'afterCreateOrder'://创建出库单后
                break;
            case 'beforePack'://打包前
                break;
            case 'afterPack'://打包后
                break;
            case 'beforeOutbound'://出库前
                break;
            case 'afterOutbound'://出库后
                break;
            case 'beforeDisposal'://销毁前
                break;
            case 'afterDisposal'://销毁后
                break;
            case 'beforeReturn'://退货前
                break;
            case 'afterReturn'://退货后
                break;
        }
        return $eventData;
    }
}


2、注册钩子服务:common/config/main.php

'components' => [
        //......
        'hookManager' => [
            'class' => 'common\components\HookManager',
        ],
        //......
  ]


3、统一入口执行:


    public function beforeAction($action)
    {
        // 注册钩子 START
        Yii::$app->hookManager->on('beforeReservation', function($eventData) {});//预约前
        Yii::$app->hookManager->on('afterReservation', function($eventData) {});//预约后
        Yii::$app->hookManager->on('beforeInbound', function($eventData) {});//入库前
        Yii::$app->hookManager->on('afterInbound', function($eventData) {});//入库后
        Yii::$app->hookManager->on('beforePutaway', function($eventData) {});//上架前
        Yii::$app->hookManager->on('afterPutaway', function($eventData) {});//上架后
        Yii::$app->hookManager->on('beforeCreateOrder', function($eventData) {});//创建出库单前
        Yii::$app->hookManager->on('afterCreateOrder', function($eventData) {});//创建出库单后
        Yii::$app->hookManager->on('beforePack', function($eventData) {});//打包前
        Yii::$app->hookManager->on('afterPack', function($eventData) {});//打包后
        Yii::$app->hookManager->on('beforeOutbound', function($eventData) {});//出库前
        Yii::$app->hookManager->on('afterOutbound', function($eventData) {});//出库后
        Yii::$app->hookManager->on('beforeDisposal', function($eventData) {});//销毁前
        Yii::$app->hookManager->on('afterDisposal', function($eventData) {});//销毁后
        Yii::$app->hookManager->on('beforeReturn', function($eventData) {});//退货前
        Yii::$app->hookManager->on('afterReturn', function($eventData) {});//退货后
        //触发实例:Yii::$app->hookManager->trigger('afterInbound', $eventData);
        // 注册钩子 END
      }


4、埋钩子(即在需要执行钩子程序时插入代码)


    //钩子
    $eventDataAfter = [];
    Yii::$app->hookManager->trigger('afterReservation', $eventDataAfter);