• 利用 Composer 完善自己的 PHP 框架(二)——发送邮件


    本教程示例代码见 https://github.com/johnlui/My-First-Framework-based-on-Composer


    回顾

    上一篇文章中,我们手工建造了一个简易的视图加载器,顺便引入了错误处理包,让我们的 MFFC 框架在 M、V、C 三个方面都达到了“好用”的水平。View 是一个可插拔组件,在本篇文章中我们要创建另一个可插拔组件——邮件发送模块。

    正文

    我们采用 'nette/mail' 包作为我们的邮件发送基础模块,在它的基础上封装一个 'Mail' 类,暴露出简洁的 API 给控制器使用,下面我们正式开始。

    引入 'nette/mail' 包,修改 'composer.json':

    "require": {
    
      "codingbean/macaw": "dev-master",
    
      "illuminate/database": "*",
    
      "filp/whoops": "*",
    
      "nette/mail": "*"
    
    },
    

    运行 'composer update',等待安装完成。'nette/mail' 的文档位于:http://doc.nette.org/en/2.2/mailing 让我们阅读它,然后设计 Mail 类:

    新建 'services/Mail.php' 文件,内容如下:

    <?php
    
    use NetteMailMessage;
    
    /**
    
    * Mail
    
    */
    
    class Mail extends Message
    
    {
    
      public $config;
    
      // [String] e-mail
    
      protected $from;
    
      // [Array] e-mail list
    
      protected $to;
    
      protected $title;
    
      protected $body;
    
      function __construct($to)
    
      {
    
        $this->config = require BASE_PATH.'/config/mail.php';
    
        $this->setFrom($this->config['username']);
    
        if ( is_array($to) ) {
    
          foreach ($to as $email) {
    
            $this->addTo($email);
    
          }
    
        } else {
    
          $this->addTo($to);
    
        }
    
      }
    
      public function from($from=null)
    
      {
    
        if ( !$from ) {
    
          throw new InvalidArgumentException("邮件发送地址不能为空!");
    
        }
    
        $this->setFrom($from);
    
        return $this;
    
      }
    
      public static function to($to=null)
    
      {
    
        if ( !$to ) {
    
          throw new InvalidArgumentException("邮件接收地址不能为空!");
    
        }
    
        return new Mail($to);
    
      }
    
      public function title($title=null)
    
      {
    
        if ( !$title ) {
    
          throw new InvalidArgumentException("邮件标题不能为空!");
    
        }
    
        $this->setSubject($title);
    
        return $this;
    
      }
    
      public function content($content=null)
    
      {
    
        if ( !$content ) {
    
          throw new InvalidArgumentException("邮件内容不能为空!");
    
        }
    
        $this->setHTMLBody($content);
    
        return $this;
    
      }
    
    }
    

    Mail 类和 View 类工作的方式基本一致:

    $this->mail = Mail::to(['ooxx@gmail.com', 'ooxx@qq.com'])
    
                        ->from('MotherFucker <ooxx@163.com>')
    
                        ->title('Fuck Me!')
    
                        ->content('<h1>Hello~~</h1>');
    

    上面这段代码位于 HomeController 中, 'View::make()' 那行代码的下面。

    新建 'MFFC/config/mail.php',请自行替换邮件地址和密码:

    <?php
    
    return [
    
      'host' => 'smtp.163.com',
    
      'username' => 'ooxx@163.com',
    
      'password' => 'password',
    
      'secure' => ''
    
    ];
    

    Mail 和 View 一样也在 BaseController 的析构函数 __destruct() 函数中处理,现在这个 function 长这样:

    public function __destruct()
    
    {
    
      $view = $this->view;
    
      if ( $view instanceof View ) {
    
        extract($view->data);
    
        require $view->view;
    
      }
    
      $mail = $this->mail;
    
      if ( $mail instanceof Mail ) {
    
        $mailer = new NetteMailSmtpMailer($mail->config);
    
        $mailer->send($mail);
    
      }
    
    }
    

    OK,准备的差不多了,运行 'composer dump-autoload' 把 Mail 类加入自动加载,刷新页面!

    Image

    如果你看到以上页面,恭喜你!邮件发送成功了!

    赶快去检查一下收件箱有木有邮件!:-D 这次页面加载可能会稍慢,因为邮件是同步发送的。异步的队列系统我们会在以后讲到。

    分析

    邮件发送的整体流程想必大家已经轻车熟路了,现在主要叙述一下 Mail 类的设计过程:

    1. 邮件发送的核心参数是 '目标地址',即邮件要发送到的 E-mail 地址,所以我们设计 Mail::to('oo@xx.me') 作为发送的 '触发 API'。
    2. 目前我们采用最简单的 'SMTP' 方式发送邮件,文档在 这里。配置文件放置在 'MFFC/config/mail.php' 中,依旧返回一个数组。
    3. Mail 类继承了 'NetteMailMessage' 类。'Mail::to()' 的时候创建一个 Mail 类的实例(对象)并返回,这时候其实 'BaseController' 中的析构函数中的代码已经会被触发并处理这个对象了。默认的发送人是从配置文件中读取的 'username'。
    4. 'Mail::to()' 支持 字符串 或者数组作为参数,可以一次发送一封或多封邮件。
    5. 'from()'、'title()' 和 'content()' 方法用于丰富邮件内容。'content()' 方法可以直接传递 HTML 代码。
    6. 'from()' 配置不一定都能够成功,部分邮件服务商不支持修改发送人地址。
    7. 这个变量全部组装完成后,被赋值给控制器的 '$mail' 成员变量,然后被析构函数处理,邮件被发送,成功后页面代码被发送回客户端,流程结束。

    https://lvwenhan.com/php/412.html

  • 相关阅读:
    Arr
    class4
    class3联大网页
    class33
    class3
    人机交换 NO 1书签
    大数据的框架与特点
    mapreduce排序
    mapreduce求平均数
    mapreduce去重
  • 原文地址:https://www.cnblogs.com/chunguang/p/5593510.html
Copyright © 2020-2023  润新知