Laravel 中类似 WordPress 的钩子和过滤器

36 篇文章 0 订阅
9 篇文章 0 订阅

WordPress 中最强大的工具之一是它使用的钩子系统。这是从任何地方修改值的好方法。它为任何 WordPress 网站增加了巨大的灵活性。让我们看一下,如何在 Laravel 中实现这一点

 

基本概念

基本思想与 WordPress 钩子系统其实是一样的。代码中的某处有一些值,我们希望从外部轻松修改它们,而无需修改任何代码。此外,设置优先级会很好,因为我们可以更好地控制修改

事件与钩子

如果我们可以使用 Laravel 的事件系统来实现这个功能,那就太好了,但这并不理想。因此,我们将实现一个小型钩子存储库,它将根据优先级存储和排序已注册的钩子

 

挂钩存储库

这个存储库将是一个非常简单的地方来存储我们的钩子并在我们需要时使用它们

 

class HookRepository
{
    /**
     * The repository items.
     *
     * @var \Illuminate\Support\Collection
     */
    protected $items;

    /**
     * Create a new repository instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->items = collect();
    }

    /**
     * Dynamically call methods.
     *
     * @param  string  $method
     * @param  array  $arguments
     * @return mixed
     */
    public function __call(string $method, array $arguments)
    {
        return $this->items->{$method}(...$arguments);
    }

    /**
     * Register a new hook callback.
     *
     * @param  string|array  $hook
     * @param  callable  $callback
     * @param  int  $priority
     * @return void
     */
    public function register($hook, callable $callback, int $priority = 10): void
    {
        $this->items->push(compact('hook', 'callback', 'priority'));
    }

    /**
     * Apply the callbacks on the given hook and value.
     *
     * @param  string  $hook
     * @param  array  $arguments
     * @return mixed
     */
    public function apply(string $hook, ...$arguments)
    {
        return $this->items->filter(function ($filter) use ($hook) {
            return !! array_filter((array) $filter['hook'], function ($item) use ($hook) {
                return Str::is($item, $hook);
            });
        })->sortBy('priority')->reduce(function ($value, $filter) use ($arguments) {
            return call_user_func_array($filter['callback'], [$value] + $arguments);
        }, $arguments[0] ?? null);
    }
}

所以,我们这里有两个方法,registerapply。所有其他调用将被转发到持有钩子的集合实例 

我们可以在服务提供者中注册钩子,例如 :

public function boot()
{
    Hook::register('jobs.tags', function ($tags, $job) {
        return array_merge($tags, $job->someCondition() ? ['foo'] : ['bar']);
    });
}

请注意,使用这种方法,我们也可以使用通配符或数组表示法注册挂钩。

例如:[jobs.tags, posts.tags]或jobs.* 

应用挂钩

那么,在哪里应用钩子呢?基本上你想要的任何地方。该解决方案的好处是,您实际上并不需要针对不同地方的复杂价值管理器。您可以使用钩子,传递您想要的任何参数,并返回稍后将使用的修改后的值

public function tags()
{
    return Hook::apply('jobs.tags', ['a', 'b'], $this);
}

我们调用apply方法并首先传递钩子和值,然后是回调中可能需要的任何其他参数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

rorg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值