Laravel5.6使用定時任務實現定時發郵件

1、建立項目

一、打開終端,執行命令:laravel new crontab,包括數據庫,確保本地能正常運行。隨後部署上線。phpstrom鏈接服務器,確保代碼能夠正常提交到服務器。
二、建立任務類,終端執行命令:php artisan make:command SendEmail
三、修改 SendEmail.php 文件php

protected $signature = 'email:send';
protected $description = '定時發郵件測試';
複製代碼

四、先不慌作發郵件,先來個文件定時寫入測試,在文件中寫入當前時間,代碼以下html

public function handle()
{
  //寫入文件
  file_put_contents("/var/www/crontab/file.txt", date('Y-m-d H:i:s') . PHP_EOL, FILE_APPEND);
}
複製代碼

注:這裏的PHP_EOL表明時間列表換行,後面的FILE_APPEND是指日後追加一條記錄。laravel

五、修改app/Console/Kernel.php文件:web

protected $commands = [
    Commands\SendEmail::class //註冊任務類
];

protected function schedule(Schedule $schedule)
{
    //每分鐘執行一次文件的寫入
    $schedule->command('email:send')
        ->everyMinute();
}
複製代碼

六、服務器上,進入項目:cd /var/www/crontab,先查看服務器上PHP安裝路徑,執行命令:which php,個人PHP路徑是/usr/bin/php,而後把路徑複製保存下來,接着執行命令:crontab -e,選擇打開方式,建議選擇第4個。在最後一行增長以下代碼:redis

* * * * * /usr/bin/php /var/www/crontab/artisan schedule:run >> /dev/null 2>&1
複製代碼

注:這裏前面一部分/usr/bin/php表明服務器上PHP的安裝路徑,後面一部分表明項目目錄。
另外上面的命令前面的5個星號*分別表明分鐘、小時、天、月、星期。
分鐘:0-59的整數,默認星號和星號/1 表明1分鐘。
小時:0-23的整數。
天:1-31的整數。
月:1-12的整數。
星期:0-7的整數,0和7都表明星期日。
crontab -l 能夠列出當前的定時任務。數據庫

七、啓動任務sudo service cron restart,打開FZ,查看服務器上項目的根目錄下的file.txt文件中是否有時間寫入而且每分鐘執行一次。確認成功後,執行命令 service cron stopexit退出定時任務。後端

2、實現定時發郵件

接下來要作的是把寫入文件的操做換成定時發郵件。在.env文件配置發郵件所需的相關信息。瀏覽器

MAIL_DRIVER=smtp
MAIL_HOST=smtp.qq.com
MAIL_PORT=465
MAIL_USERNAME=發件人郵箱
MAIL_PASSWORD=發件人郵箱郵箱密碼
MAIL_ENCRYPTION=ssl
MAIL_FROM_ADDRESS=發件人郵箱
MAIL_FROM_NAME=發件人名字
複製代碼

一、打開web.php,添加路由bash

$this->any('mail', 'HomeController@mail');//發郵件
複製代碼

二、在Home控制器中添加以下代碼:服務器

public function mail()
{
   //第一種方法
   \Mail::raw('定時發送郵件 測試', function ($message) {
       $message->from('發件人郵箱', '長樂未央');
       $message->subject('郵件主題 測試');
       $message->to('收件人郵箱');
   });

  //第二種方法
// \Mail::send('admin.mail', ['name' => 'holy'], function ($message) {
//     $message->to('收件人郵箱');
// });
}
複製代碼

測試:終端打印路由,拿到路由地址去瀏覽器中訪問:http://你的二級域名/admin/mail,查看郵箱是否收到郵件。若是成功收到郵件,請繼續往下。。

三、打開任務類 SendEmail.php文件,修改handle方法,代碼以下:

public function handle()
{
//寫入文件
// file_put_contents("/var/www/crontab/file.txt", date('Y-m-d H:i:s') . PHP_EOL, FILE_APPEND);

 \Mail::raw('定時發送郵件 測試', function ($message) {
    //查出要發郵件的全部用戶的郵箱
    $customers = Customer::where('email', '<>', null)->get();
    foreach ($customers as $customer) {
         $message->from('發件人郵箱', '發件人名字');
         $message->subject('郵件主題 測試');

          //執行發送
         $message->bcc($customer->email);
      }
    });
}
複製代碼

最後去服務器的當前項目中,啓動定時命令 service cron restart,等一分鐘,查看郵箱是否收到郵件而且每一分鐘執行一次。

3、增長Redis隊列

當咱們要發的郵件量很大時,咱們就要使用到隊列,把要發送的郵件所有存入隊列,讓後端去完成這個漫長的操做。網上不少資料都是使用數據庫隊列,我這裏使用 redis隊列。

一、修改.env文件中的 QUEUE_DRIVER=syncQUEUE_DRIVER=redis
二、啓動隊列,終端執行命令:redis-server,你會發現predis的擴展沒裝,執行命令:composer require predis/predis安裝便可。安裝完成後,從新啓動redis。
三、建立任務類:php artisan make:job SendReminderEmail,運行成功後會在app/Jobs目錄下生成一個SendReminderEmail.php,咱們修改其內容以下:

<?php
namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

use App\Customer;
use Illuminate\Contracts\Mail\Mailer;
class SendReminderEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    protected $customer;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(Customer $customer)
    {
        $this->customer = $customer;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle(Mailer $mailer)
    {
        $customer = $this->customer;

        $mailer->send('emails.reminder',['customer'=>$customer],function($message) use ($customer){
            $message->to($customer->email)->subject('新功能發佈');
        });
    }
}
複製代碼

四、建立郵件局部視圖resources/views/emails/reminder.blade.php

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div>
        親愛的{{$customer->nickname}},您好,長樂教育新發布了Laravel5.6使用redis實現羣發郵件功能,當即去體驗下吧:
        <a href="https://www.whphp.com/">前往長樂教育</a>
    </div>
</body>
</html>複製代碼

4、推送隊列任務---手動分發任務

一、在web.php中添加以下路由:

Route::get('mail/sendReminderEmail/{id}','MailController@sendReminderEmail');
複製代碼

二、建立控制器:php artisan make:controller MailController,控制器中寫入以下代碼:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests;
use App\Customer;
use Mail;
use Storage;
use App\Jobs\SendReminderEmail;
class MailController extends Controller
{
    //發送提醒郵件
    public function sendReminderEmail(Request $request, $id)
    {
        $customer = Customer::findOrFail($id);

        $this->dispatch(new SendReminderEmail($customer));
    }
}
複製代碼

三、運行隊列監聽器。在瀏覽器中訪問http://你的二級域名/mail/sendReminderEmail/1,此時任務被推送到Redis隊列中。在命令行中運行以下命令:php artisan queue:work,而後去查看郵箱會收到提醒郵件:

四、推送任務到指定隊列,修改App\Console\Commands\SendEmail裏面的handle方法代碼以下:

public function handle()
{
  \Mail::queue('定時發送郵件 測試', function ($message) {
      //查出要發郵件的全部用戶的郵箱
      $customers = Customer::where('email', '<>', null)->get();
      foreach ($customers as $customer) {
           $message->from('244500972@qq.com', 'huangdj');
           $message->subject('郵件主題 測試');

         //執行發送
        //$message->bcc($customer->email);

        //將任務推送到指定隊列並延遲一分鐘執行
        dispatch(new \App\Jobs\SendReminderEmail($customer->email))->onQueue('emails')->delay(60);
      }
  });
}
複製代碼

終極測試:看郵箱是不是每隔一分鐘收到一份郵件
啓動:redis-server
啓動:php artisan queue:work
啓動定時執行:service cron restart

轉至 長樂 http://itfun.tv 黃老師

相關文章
相關標籤/搜索