问题描述
我想重写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
, extendingIlluminate\Mail\Mailer
, in which you can override thesend
method, implement your checks and callparent::send()
. - Write your own service provider (Extending
Illuminate\Mail\MailServiceProvider
), in particular re-implement theregister
method. It should create an instance of your ownMailer
in place of Laravel's own. (You can copy most of the code from Laravel'sregister
method). - Now, in your
config/app.php
file, in theproviders
array, replaceIlluminate\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.
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方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!