Скрипт рассылки на PHP выполняется несколько раз (с использованием Mailgun)

#php #mysql #email #slim #mailgun

#php #mysql #Адрес электронной почты #тонкий #mailgun

Вопрос:

У нас есть PHP-скрипт, который должен отправлять электронные письма всем пользователям, которые соответствуют определенным критериям. Скрипт использует Mailgun для обработки рассылки. Скрипт отлично работает с небольшим количеством записей (около 500 или меньше), однако, если записей становится слишком много (скажем, 1000, 2000), скрипт не завершается и вместо этого запускается несколько раз (пользователи получают одно и то же электронное письмо два или три раза).).

 require __DIR__ . '/../vendor/autoload.php';
use MailgunMailgun;

# Instantiate the client.
$mgClient = new Mailgun('our-private-key');
$mgClient1= new Mailgun('our-public-key');
$domain = "our.domain";

// 1. Connect to database

$pdo = new PDO('mysql:host=localhost;dbname=db', 'user', 'psw');
$pdo->exec('SET NAMES "utf8"');


// 2. Query users table for any records where field "endDate" < the current time

$query = "SELECT userId, firstName, email FROM users WHERE endDate <= now() AND sub = 0";
$expiredQuery = $pdo->prepare($query);
$expiredQuery->execute();

$expired = $expiredQuery->fetchAll(PDO::FETCH_OBJ);

if (empty($expired)) {
    echo 'There are no records to unsubscribe.';
    exit();
}


// 3. If found, loop through results and get the "uId"; save users to a users array

$ids = [];
$usernames = [];
$emails = [];

foreach ($expired as $user) {
  $id = $user->uId;
  $username = $user->fName;
  $useremail = $user->email;
  array_push($ids, $id);
  array_push($usernames, $username);
  array_push($emails, $useremail);
}


// 4. Send email to users

$counter = 0;

foreach ($emails as $email) {

  # Issue the call to the client.
  $resultVer = $mgClient1->get("address/validate", array('address' => $email));
  # is_valid is 0 or 1
  $isValid = $resultVer->http_response_body->is_valid;


  if (!$isValid) {
    echo "Not delivered: " . $email . "<br>"; 
    $counter  ;
    continue;
  }

  $firstname = $usernames[$counter];

  # Build recipient email
  $rec_msg = 'Hi '.$firstname.'... etc etc';

  # Send mail to recipient
  $result = $mgClient->sendMessage($domain, array(
    'from'    => 'Sender<Sender@sender.com>',
    'to'      => $email,
    'subject' => 'An email',
    'html'    => $rec_msg,

  ), array(
    'inline'  => array('http://www.oursite.com/images/mail_header.jpg', 'http://www.oursite.com/images/footer.jpg')
  ));

  # Increment the counter
  $counter  ;
}


// 6. Send notification

echo "The following users were sent an email <br>" . implode(", ", $emails);
die();
  

Я попытался добавить die() в конце, но это не помогло. Также я не получаю никаких выходных данных между несколькими запусками скрипта.

Ответ №1:

Во-вторых, чтобы предотвратить одновременный запуск сценария рассылки несколько раз, я бы рекомендовал использовать блокирующий компонент, такой как symfony /lock.

Другая проблема заключается в количестве электронных писем, которые вы пытаетесь отправить одновременно. Попробуйте разделить количество писем на более мелкие части, например, 500 за один раз. Вы можете использовать SQL LIMIT x,y фильтр или извлечь все строки и разделить строки с помощью array_chunk.