如何覆盖Laravel Facade方法? [英] How can I override Laravel Facade methods?

查看:235
本文介绍了如何覆盖Laravel Facade方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想重写Laravels Mail的class门面方法send(只是拦截它,强制执行一些检查,然后如果它通过触发parent :: send()的话)

I want to override the Laravels' Mail's classes facade method send (just intercept it forcing some checks and then if it passes triggering parent::send())

做到这一点的最佳方法是什么?

What is the best way to do this?

推荐答案

Facade不能那样工作.从本质上讲,它类似于一个包装器类,该包装器类调用其表示的基础类.

A Facade doesn't work like that. It's essentially kind of like a wrapper class that calls the underlying class that it represents.

Mail外观实际上没有send方法.当执行Mail::send()时,在幕后将使用外观访问器"来引用绑定在IoC容器中的Illuminate\Mail\Mailer类的实例.在该对象上调用send方法.

The Mail facade doesn't actually have a send method. When you do Mail::send(), under the hood, the "facade accessor" is used to reference an instance of the Illuminate\Mail\Mailer class bound in the IoC container. It's on that object the send method is called.

实现所追求的目标的方法实际上比看起来要复杂一些.您可以做的是:

The way in which you can achieve what you're after is actually a little bit trickier than it seems. What you can do is:

  • 编写自己的Mailer实现,扩展Illuminate\Mail\Mailer,在其中可以覆盖send方法,实现检查并调用parent::send().
  • 编写您自己的服务提供商(扩展Illuminate\Mail\MailServiceProvider),尤其是重新实现register方法.它应该创建您自己的Mailer的实例来代替Laravel自己的实例. (您可以从Laravel的register方法复制大多数代码.)
  • 现在,在您的config/app.php文件中的providers数组中,将Illuminate\Mail\MailServiceProvider::class,替换为您自己的提供程序.
  • Write your own implementation of Mailer, extending Illuminate\Mail\Mailer, in which you can override the send method, implement your checks and call parent::send().
  • Write your own service provider (Extending Illuminate\Mail\MailServiceProvider), in particular re-implement the register method. It should create an instance of your own Mailer in place of Laravel's own. (You can copy most of the code from Laravel's register method).
  • Now, in your config/app.php file, in the providers array, replace Illuminate\Mail\MailServiceProvider::class, with your own provider.

这应该使您能够使用Laravel的Mail功能.

That should let you hook into Laravel's Mail functionality.

有关更多信息,您可以查看以下达到类似目的的问题/答案.它扩展了邮件功能以添加新的传输驱动程序,但是采用了类似的方法,因为它提供了自己的邮件程序实现和服务提供程序.

For more information, you can take a look at the following question/answer which achieves a similar thing. It extends the Mail functionality to add a new transport driver, but it takes a similar approach in that it provides it's own Mailer implementation and service provider.

向Laravel的Mailer添加新的传输驱动程序

app/MyMailer/Mailer.php

<?php

namespace App\MyMailer;

class Mailer extends \Illuminate\Mail\Mailer
{
    public function send($view, array $data = [], $callback = null)
    {
        // Do your checks

        return parent::send($view, $data, $callback);
    }
}

app/MyMailer/MailServiceProvider.php (大多数从Laravel的MailServiceProvider类复制的代码)

app/MyMailer/MailServiceProvider.php (Most of the code copied from Laravel's MailServiceProvider class)

<?php

namespace App\MyMailer;

class MailServiceProvider extends \Illuminate\Mail\MailServiceProvider
{
    public function register()
    {
        $this->registerSwiftMailer();

        $this->app->singleton('mailer', function ($app) {
            // This is YOUR mailer - notice there are no `use`s at the top which
            // Looks for a Mailer class in this namespace
            $mailer = new Mailer(
                $app['view'], $app['swift.mailer'], $app['events']
            );

            $this->setMailerDependencies($mailer, $app);


            $from = $app['config']['mail.from'];

            if (is_array($from) && isset($from['address'])) {
                $mailer->alwaysFrom($from['address'], $from['name']);
            }

            $to = $app['config']['mail.to'];

            if (is_array($to) && isset($to['address'])) {
                $mailer->alwaysTo($to['address'], $to['name']);
            }

            return $mailer;
        });
    }
}

config/app.php (在providers数组中)

config/app.php (In the providers array)

//...
// Illuminate\Mail\MailServiceProvider::class,
App\MyMailer\MailServiceProvider::class,
//...

这篇关于如何覆盖Laravel Facade方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆