я использую SwiftMailer отправлять массовые письма. На данный момент я делаю это с кодом
$transport = Swift_SmtpTransport::newInstance('*****', 25);
$transport->setUsername('***');
$transport->setPassword('***');
$mailer = Swift_Mailer::newInstance($transport);
$message = Swift_Message::newInstance();
$message->setSubject($derBetreff);
$bbc= array('[email protected]','[email protected]','[email protected]',...,'[email protected]');
$message->setFrom(array('[email protected]' => 'My Name'));
$message->setTo('[email protected]');
$message->setBcc($bcc);
$message->setBody('Hi this is my email');
$message->attach(Swift_Attachment::fromPath('myFile.pdf'));
// Send the message
$result = $mailer->send($message);
echo $result;
где я отправляю только одно электронное письмо и добавляю ~ 1000 человек в BCC.
Выполнение кода и отправка одного сообщения электронной почты занимает около 9 минут, и возвращается сообщение об успехе. Тем не менее, мой max_execution_time в моем файле php.ini установлено только 30 секунд.
Мой первый вопрос: почему max_execution_time не останавливает мой скрипт SwiftMailer?
Во-вторых, я нашел Плагин AntiFlood для Swiftmailer который помогает отправлять массовые электронные письма. Сценарий, приведенный ниже, отправляет каждому участнику по одному электронному письму, сначала отправляя 100 писем, а затем делает паузу в течение 30 секунд и продолжает отправку следующих 100 писем и так далее. Я читал, что это хорошая практика, чтобы обойти пометку как спам.
Мой второй вопрос: нужно ли плагину AntiFlood необычайно долгое время выполнения для работы? Например, если я отправлю 1000 писем с помощью приведенного ниже сценария и приму только паузу, то сценарий будет запущен уже не менее 4,5 минут, верно?
// Create the Mailer using any Transport
$mailer = Swift_Mailer::newInstance(
Swift_SmtpTransport::newInstance('smtp.example.org', 25)
);
// Use AntiFlood to re-connect after 100 emails
$mailer->registerPlugin(new Swift_Plugins_AntiFloodPlugin(100));
// And specify a time in seconds to pause for (30 secs)
$mailer->registerPlugin(new Swift_Plugins_AntiFloodPlugin(100, 30));
// Continue sending as normal
for ($lotsOfRecipients as $recipient) {
...
$mailer->send( ... );
}
Для отправки массовых писем Вам следует воспользоваться услугой брокера, такой как RabbitMQ. Вы должны создать 2 очереди, одну для объединения писем, а другую для отправки электронной почты с помощью Swiftmailer. Каждое письмо будет сообщением rabbitMq.
Прежде всего, отправка электронных писем не происходит в самом скрипте. Вот почему max_execution_time не затрагивается, если ваш сервер работает в Linux, см. документы:
Функция set_time_limit () и директива конфигурации
max_execution_time влияет только на время выполнения скрипта
сам. Любое время, потраченное на деятельность, которая происходит за пределами исполнения
сценария, таких как системные вызовы с использованием system (), потоковые операции,
запросы к базе данных и т. д. не учитываются при определении максимального
время, когда скрипт был запущен. Это не так в Windows
где измеренное время реально.
Таким образом, используя Anti-Flood Плагин — хорошая идея, когда вы отправляете несколько писем одновременно.
Тем не менее, я думаю, что лучше хранить электронные письма в базе данных, и пусть cronjob отправляет X писем из БД каждые Y минут. Таким образом, у вас нет загрузочного скрипта, который занимает несколько минут перед вами (включая опасность повторной отправки, если страница будет перезагружена). Если вы используете фреймворк, такой как Laravel, то вы можете использовать встроенный почта-запрос особенность, которая делает именно это.