[灵性编程]函数委托,自动事件,函数观察者

一直想写点技术博客,又没有特别想写的,太过简单的动态一搜一大推,太复杂的自己都没搞懂,只有写写技巧了。。。

库地址: github.com/ctfang/laravel-watch

laravel 业务函数委托执行

函数委托执行,特别适用于扩展业务时又不需要侵入原有代码。

安装

composer require ctfang/laravel-watch

如果使用Phpstorm, 可以安装扩展 PHP Annotations 方便提示。

使用

在app目录下任意类的函数注释上加 @Watch(test::class,"func") 就会自动经过 test->func

1。先设计一个场景,一个登陆需求。
原来代码是这样的,只实现了登陆功能,成功返回用户信息。

<?php


namespace App\Http\Controllers\User;


use Illuminate\Http\Request;

class LoginController
{
    public function login(Request $request)
    {
        // 登陆成功
        return ['request' => $request , 'user_id' => 1];
    }
}

2。需求有变动,需要加上登陆流水、登陆途径和流失记录(登陆失败也记录)

新增逻辑类 LoginLogic, 实现逻辑

<?php


namespace App\Logics\User;


use Ctfang\LaravelWatch\Context;

class LoginLogic
{
    /**
     * 记录上传参数
     * @param  \Ctfang\LaravelWatch\Context  $context
     * @param  \Closure  $next
     * @return mixed
     */
    public function watchLogin(Context $context, \Closure $next)
    {
        /** @var \Illuminate\Http\Request $request 输入参数获取 */
        $request = $context->getInput('request');

        // 逻辑处理

        // 途径处理完后再登陆
        return $next($context);
    }

    /**
     * 记录登陆日记
     * @param  \Ctfang\LaravelWatch\Context  $context
     * @param  \Closure  $next
     * @return mixed
     */
    public function loginLog(Context $context, \Closure $next)
    {
        // 登陆成功后才记录流失
        $response = $next($context);
        $userId   = $response['user_id'];

        // 记录逻辑

        return $response;
    }
}

修改 LoginController 文件新增注释代码, 注意注释的类使用也是要use进来的

<?php


namespace App\Http\Controllers\User;


use Illuminate\Http\Request;
use Ctfang\LaravelWatch\Annotations\Watch;
use App\Logics\User\LoginLogic;

class LoginController
{
    /**
     * @Watch(LoginLogic::class,"watchLogin")
     * @Watch(LoginLogic::class,"loginLog")
     */
    public function login(Request $request)
    {
        return ['request' => $request , 'user_id' => 1];
    }
}

注意

为了更方便委托,logic类必须需要make方式或者laravel注入方式实例类

例如一个查看用户info的函数需要代理,controller 函数需要这样子写,LoginLogic需要注入或者app('LoginLogic')

    public function info(Request $request, LoginLogic $logic)
    {
        $userId = $request->input('user_id');

        return ['user' => $logic->info($userId)];
    }

info的函数代码


    /**
     * @Watch(LoginLogic::class,'infoWatch')
     */
    public function info(int $id)
    {
        return [];
    }

    public function infoWatch(Context $context, \Closure $next)
    {
        $id = $context->getInput('id');

        echo "玩家被读取" . $id;
    }
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 3
porygonCN

大佬666, 昨天刚在想如何设置在任意方法执行前先执行其他操作 , 今天就看到了 已Star

2年前 评论

这不是事件,是委托,代理,观察者,事件要手动穿参数,业务变更参数也要变,观察者是比事件好维护一点的。

2年前 评论

如果是事件方式。例如你做商城,购买后要记录订单流水,货币消耗流水,不同物品类型又有不同流水,如果是事件方式,购买函数要好多逻辑的,根据不同类型选着行触发不同事件,当热可以设计成多监听器做,但是在需求一点点出的时候,已经好的业务事件不太建议更改,新增新的业务事件比修改原有代码更符合实际情况。

观察者方式不一样,不用改事件类,它能直接观察所有变化。

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!