Mail

Testing Is Documentation

tests/Mail/MailTest.phpMail - 图1

邮件发送统一由邮件组件完成,通常我们使用代理 \Leevel\Mail\Proxy\Mail 类进行静态调用。

QueryPHP 的邮件底层为 swiftmailer/swiftmailer,系统进行了简单的一层封装。

内置支持的邮件驱动类型包括 smtp、sendmail、test,未来可能增加其他驱动。

使用方式

使用容器 mails 服务

  1. \App::make('mails')->html(string $content): \Leevel\Mail\IMail;

依赖注入

  1. class Demo
  2. {
  3. private \Leevel\Mail\Manager $mail;
  4. public function __construct(\Leevel\Mail\Manager $mail)
  5. {
  6. $this->mail = $mail;
  7. }
  8. }

使用静态代理

  1. \Leevel\Log\Proxy\Log::html(string $content): \Leevel\Mail\IMail;

mail 配置

系统的 mail 配置位于应用下面的 option/mail.php 文件。

可以定义多个邮件连接,并且支持切换,每一个连接支持驱动设置。

  1. <?php
  2. declare(strict_types=1);
  3. /*
  4. * This file is part of the your app package.
  5. *
  6. * The PHP Application For Code Poem For You.
  7. * (c) 2018-2099 http://yourdomian.com All rights reserved.
  8. *
  9. * For the full copyright and license information, please view the LICENSE
  10. * file that was distributed with this source code.
  11. */
  12. return [
  13. /*
  14. * ---------------------------------------------------------------
  15. * 邮件驱动
  16. * ---------------------------------------------------------------
  17. *
  18. * 采用什么方式发送邮件数据
  19. */
  20. 'default' => Leevel::env('MAIL_DRIVER', 'smtp'),
  21. /*
  22. * ---------------------------------------------------------------
  23. * 邮件发送地址
  24. * ---------------------------------------------------------------
  25. *
  26. * 必须设置邮件发送的邮箱
  27. */
  28. 'global_from' => [
  29. 'address' => Leevel::env('MAIL_GLOBAL_FROM_ADDRESS'),
  30. 'name' => Leevel::env('MAIL_GLOBAL_FROM_NAME'),
  31. ],
  32. /*
  33. * ---------------------------------------------------------------
  34. * 邮件全局接收地址
  35. * ---------------------------------------------------------------
  36. *
  37. * 这个可以不用设置,如果设置所有邮件都会发送一份到这个邮箱
  38. */
  39. 'global_to' => [
  40. 'address' => null,
  41. 'name' => null,
  42. ],
  43. /*
  44. * ---------------------------------------------------------------
  45. * 邮件驱动连接参数
  46. * ---------------------------------------------------------------
  47. *
  48. * 这里为所有的邮件驱动的连接参数,每一种不同的驱动拥有不同的配置
  49. * 虽然有不同的驱动,但是在使用上却有着一致性
  50. */
  51. 'connect' => [
  52. 'smtp' => [
  53. // driver
  54. 'driver' => 'smtp',
  55. // smtp 主机
  56. 'host' => Leevel::env('MAIL_HOST', 'smtp.qq.com'),
  57. // 端口
  58. 'port' => (int) Leevel::env('MAIL_PORT', 587),
  59. // 用户名
  60. 'username' => Leevel::env('MAIL_USERNAME'),
  61. // 登录密码
  62. 'password' => Leevel::env('MAIL_PASSWORD'),
  63. // 加密方式
  64. 'encryption' => Leevel::env('MAIL_ENCRYPTION', 'ssl'),
  65. ],
  66. 'sendmail' => [
  67. // driver
  68. 'driver' => 'sendmail',
  69. // 命令路径
  70. 'path' => '/usr/sbin/sendmail -bs',
  71. ],
  72. 'test' => [
  73. // driver
  74. 'driver' => 'test',
  75. ],
  76. ],
  77. ];

mail 参数根据不同的连接会有所区别,通用的 mail 参数如下:

配置项配置描述
global_from邮件发送地址
global_to邮件全局接收地址

Uses

  1. <?php
  2. use Leevel\Mail\Mail;
  3. use Leevel\Mail\Smtp;
  4. use Leevel\Router\View;
  5. use Leevel\View\Phpui;
  6. use Swift_Attachment;
  7. use Swift_Message;
  8. use Swift_Mime_SimpleMessage;

plain 纯文本邮件内容

  1. public function testBaseUse(): void
  2. {
  3. $mail = $this->makeMail();
  4. $mail->plain('hello');
  5. $result = $mail->flush();
  6. $this->assertSame(1, $result);
  7. $this->assertSame([], $mail->failedRecipients());
  8. }

html HTML 邮件内容

  1. public function testHtml(): void
  2. {
  3. $mail = $this->makeMail();
  4. $mail->html('<b style="color:red;">hello</b>');
  5. $result = $mail->flush();
  6. $this->assertSame(1, $result);
  7. }

html HTML 邮件内容支持多次添加

  1. public function testHtmlMulti(): void
  2. {
  3. $mail = $this->makeMail();
  4. $mail->html('<b style="color:red;">hello</b>');
  5. $mail->html('<b style="color:blue;">world</b>');
  6. $result = $mail->flush();
  7. $this->assertSame(1, $result);
  8. }

view 视图 HTML 邮件内容

fixture 定义

mail1.php

  1. <h1>mail1 template</h1>
  2. <div style="background:blue;color:#fff;padding:10px;width:100px;">
  3. foo <?php echo $foo; ?>
  4. </div>
  1. public function testView(): void
  2. {
  3. $mail = $this->makeMail();
  4. $mail->view(__DIR__.'/assert/mail1.php', ['foo' => 'bar']);
  5. $result = $mail->flush();
  6. $this->assertSame(1, $result);
  7. }

view 视图 HTML 邮件内容支持多次添加

  1. public function testViewMulti(): void
  2. {
  3. $mail = $this->makeMail();
  4. $mail->view(__DIR__.'/assert/mail1.php', ['foo' => 'bar']);
  5. $mail->view(__DIR__.'/assert/mail1.php', ['foo' => 'hello']);
  6. $result = $mail->flush();
  7. $this->assertSame(1, $result);
  8. }

viewPlain 视图纯文本邮件内容

  1. public function testViewPlain(): void
  2. {
  3. $mail = $this->makeMail();
  4. $mail->viewPlain(__DIR__.'/assert/mail1.php', ['foo' => 'bar']);
  5. $result = $mail->flush();
  6. $this->assertSame(1, $result);
  7. }

viewPlain 视图纯文本邮件内容支持多次添加

  1. public function testViewPlainMulti(): void
  2. {
  3. $mail = $this->makeMail();
  4. $mail->viewPlain(__DIR__.'/assert/mail1.php', ['foo' => 'bar']);
  5. $mail->viewPlain(__DIR__.'/assert/mail1.php', ['foo' => 'hello']);
  6. $result = $mail->flush();
  7. $this->assertSame(1, $result);
  8. }

attachMail 添加附件

  1. public function testAttach(): void
  2. {
  3. $mail = $this->makeMail();
  4. $mail->html('hello attach');
  5. $mail->attachMail(__DIR__.'/assert/logo.png');
  6. $result = $mail->flush();
  7. $this->assertSame(1, $result);
  8. }

attachMail 添加附件支持设置附件名字

  1. public function testAttachSupportSetFilename(): void
  2. {
  3. $mail = $this->makeMail();
  4. $mail->html('hello attach');
  5. $mail->attachMail(__DIR__.'/assert/logo.png', function (Swift_Attachment $attachment) {
  6. $attachment->setFilename('logo2.jpg');
  7. });
  8. $result = $mail->flush();
  9. $this->assertSame(1, $result);
  10. }

attachData 添加内存内容附件

  1. public function testAttachData(): void
  2. {
  3. $mail = $this->makeMail();
  4. $mail->html('hello attach');
  5. $mail->attachData(file_get_contents(__DIR__.'/assert/logo.png'), 'hello.png');
  6. $result = $mail->flush();
  7. $this->assertSame(1, $result);
  8. }

view 视图 HTML 邮件内容支持附件

fixture 定义

mail2.php

  1. <h1>mail2 template</h1>
  2. <div style="background:blue;color:#fff;padding:10px;width:100px;">
  3. <img src="<?php echo $mail->attachView($path); ?>" />
  4. </div>
  1. public function testAttachView(): void
  2. {
  3. $mail = $this->makeMail();
  4. $mail->view(__DIR__.'/assert/mail2.php', ['path' => __DIR__.'/assert/logo.png']);
  5. $result = $mail->flush();
  6. $this->assertSame(1, $result);
  7. }

plain 纯文本邮件内容

  1. public function testAttachDataView(): void
  2. {
  3. $mail = $this->makeMail();
  4. $mail->view(__DIR__.'/assert/mail3.php', ['data' => file_get_contents(__DIR__.'/assert/logo.png')]);
  5. $result = $mail->flush();
  6. $this->assertSame(1, $result);
  7. }

attachData 添加内存内容附件支持附件中文名字

  1. public function testAttachChinese(): void
  2. {
  3. $mail = $this->makeMail();
  4. $mail->html('hello attach');
  5. $mail->attachData(
  6. file_get_contents(__DIR__.'/assert/logo.png'),
  7. $mail->attachChinese('魂之挽歌.png')
  8. );
  9. $result = $mail->flush();
  10. $this->assertSame(1, $result);
  11. }

HTML 邮件优先级默认高于纯文本邮件

HTML 邮件内容与纯文本邮件内容同时存在,系统优先采用前者。

flush 函数原型

  1. # Leevel\Mail\Mail::flush
  2. /**
  3. * 发送邮件.
  4. */
  5. public function flush(?Closure $callbacks = null, bool $htmlPriority = true): int;
  1. public function testSendHtmlAndPlain(): void
  2. {
  3. $mail = $this->makeMail();
  4. $mail->plain('hello');
  5. $mail->html('<b style="color:red;">hello</b>');
  6. $result = $mail->flush();
  7. $this->assertSame(1, $result);
  8. }

可以设置纯文本邮件优先级高于 HTML 邮件

  1. public function testSendHtmlAndPlainAndPlainIsFirst(): void
  2. {
  3. $mail = $this->makeMail();
  4. $mail->plain('hello');
  5. $mail->html('<b style="color:red;">hello</b>');
  6. $result = $mail->flush(null, false);
  7. $this->assertSame(1, $result);
  8. }

message 消息回调处理

  1. public function testMessage(): void
  2. {
  3. $mail = $this->makeMail();
  4. $mail->plain('hello');
  5. $mail->message(function (Swift_Message $message) {
  6. $message->setSubject('the subject');
  7. });
  8. $result = $mail->flush();
  9. $this->assertSame(1, $result);
  10. }

flush 消息回调处理

  1. public function testFlushWithMessage(): void
  2. {
  3. $mail = $this->makeMail();
  4. $mail->plain('hello');
  5. $result = $mail->flush(function (Swift_Message $message) {
  6. $message->setSubject('the subject');
  7. });
  8. $this->assertSame(1, $result);
  9. }