Laravel 通过代理发送邮件

遇到问题:

Laravel (版本 5.5) 部署在内网,服务器 (win10-xmapp-php7.2) 只能通过特定的 http 代理访问外网。

如何让 Laravel 通过代理连接 mailgun 从而发送邮件?

解决过程:

开始找了两个论坛提问,都没有得到有效的答案。后来决定深入学习一下 Laravel 发送邮件这方面的东西,结果碰巧一下就找到解决方案了。

感谢《说一说 Laravel 邮件发送流程》

作者 coding01

链接 https://juejin.im/post/5b82715de51d4538d63b748e

在这篇文章里找到配置 mailgun 的代码位置,是在 TransportManager 类的 createMailgunDriver() 方法中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* Create an instance of the Mailgun Swift Transport driver.
*
* @return \Illuminate\Mail\Transport\MailgunTransport
*/
protected function createMailgunDriver()
{
$config = $this->app['config']->get('services.mailgun', []);

return new MailgunTransport(
$this->guzzle($config),
$config['secret'], $config['domain']
);
}

其中有个 $this->guzzle($config),感觉有门,肯定是 guzzle 相关的东西,而且还传入了个$config

继续找 guzzle() 方法,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
/**
* Get a fresh Guzzle HTTP client instance.
*
* @param array $config
* @return \GuzzleHttp\Client
*/
protected function guzzle($config)
{
return new HttpClient(Arr::add(
$config['guzzle'] ?? [], 'connect_timeout', 60
));
}

再继续找HttpClient,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Client implements ClientInterface, \Psr\Http\Client\ClientInterface
{
use ClientTrait;

/**
* @var array Default request options
*/
private $config;

/**
* Clients accept an array of constructor parameters.
*
* Here's an example of creating a client using a base_uri and an array of
* default request options to apply to each request:
*
* $client = new Client([
* 'base_uri' => 'http://www.foo.com/1.0/',
* 'timeout' => 0,
* 'allow_redirects' => false,
* 'proxy' => '192.168.16.1:10'
* ]);
*
...
}

找到啦!

new HttpClient() 的时候可以传入 $config['guzzle'] 设置 proxy。

而这个 $config 就在前面的 createMailgunDriver() 方法里,是 $config = $this->app['config']->get('services.mailgun', []);

解决方法:

config/services.php 文件中给 mailgun 增加 guzzleproxy 配置,如下

1
2
3
4
5
6
7
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
'guzzle' => [
'proxy' => env('MAILGUN_PROXY'),
],
],

然后在 .env 文件中设置好 MAILGUN_PROXY 就行了。

1
MAILGUN_PROXY=address:port

ps. 如果需要的话,别忘了运行 php artisan config:cache