Урок 8. Очередь для отправки email в Laravel


Некоторые процессы могут быть растянуты во времени. Например, необходимо отправить много писем. Если сразу в цикле вызвать функцию mail() для пары тысяч штук, то, во-первых, получим ошибку сервера, связанную со временем выполнения, а во-вторых, принимающий письма сервер может посчитать это спамом (так же как и ваш хостер). Так что давайте научимся данные процессы растягивать. Именно на примере отправки майлов и познакомимся с очередями.

Первым делом создадим место для хранения информации о наших очередях, а конкретнее – таблицу в базе данных.

php artisan queue:table
php artisan migrate
Теперь у нас есть таблица jobs. Правда, пустая.



Давайте её наполним. Создадим очередь отправки писем (которые мы отправляли). Сначала класс для задач

php artisan make:job QueueSenderEmail
Теперь файл app\JobsQueueSenderEmail.php меняем примерно так:

<?php

namespace App\Jobs;

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

use Illuminate\Support\Facades\Mail;
use App\Mail\SendMail;

class QueueSenderEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
	public $mess;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($mess)
    {
        $this->mess = $mess;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
		$toEmail = "получатель@yandex.ru";
        $mm = new SendMail($this->mess);
		Mail::to($toEmail)->send($mm);
    }
}
А файл app\Http\Controllers\SendMailController.php так:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Jobs\QueueSenderEmail;

class SendMailController extends Controller
{
	
	 public function index() {
		return view('send-email');
	}
	
    public function send($message) {
		$qs = new QueueSenderEmail($message);
		$this->dispatch($qs);
		
		return redirect()
				->back()
				->with('mess', "Сообщение $message отправлено");
	}
}
Внешне ничего не поменяется – также заходим в браузере http://localhost/new_project/public/send-email и пишем, что надо отправить. А если надо с задержкой? Тоже не проблема. Меняем в файле .env

QUEUE_CONNECTION=sync
На

QUEUE_CONNECTION=database
Ставим в коде задержку

$qs = (new QueueSenderEmail($message))->delay(now()->addMinutes(3));
		$this->dispatch($qs);
Запускаем

php artisan queue:work
И теперь письма будут отправляться с задержкой в три минуты. Тепер ьможно даже увидеть, в каком виде хранится задача в базе данных:



На следующем уроке мы подведём промежуточные итоги.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегистатьи IT, уроки по Laravel, laravel, очередь, php




Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.




Немного о подготавливаемых запросах PHP
Урок 16. Пространства имен .NET
Австралийский детектив