Napisałem skrypt, który wysyła maile z informacją do userów. Jest ich max. 500, mam też obsługę dzielenia na paczki np. po 50.
Skrypt wykonuje się w zależności od ilości wiadomości ok 3-5 min.
Chciałbym ten skrypt odpalić przez AJAX a na ekranie pokazać userowi np. pasek postępu lub wysłano 5 z 50 itd.
W sieci natknąłem się na taki sposób aby skrypt PHP po każdej sztuce zapisywał np. w sesji postęp. Drugie żądanie AJAX np. co 5 sekund zaglądało by do sesji i zwracało co tam znalazło.
Jak byście podeszli do takiego tematu?
Możesz jeszcze użyć socketów lub Server-Sent Events
Troszkę długo Ci to trwa. Czego używasz do wysyłania maili? 500maili w ~240 sekund... może dasz radę zoptymalizować troszkę sam proces przygotowania treści. A co do Twojego rozwiązania - nie widzę przeszkód, ogranicz tylko ponawianie wysyłania wiadomości do jakiejś granicznej wartości np 3 powtórzenia. W sumie to przełoży się pewnie na to, aby te dane trzymał w bazie (daty nieudanych wysyłek oraz dane adresata), stąd byś też pewnie zaciągał ilość niewysłanych maili ... coś w stylu "select * from mail_queue where mail_queue_user_id = ? AND mail_queue_sent = 0 and mail_queue_try_count < 5"
Rozumiem też że każdy mail zawiera spersonalizowaną treść np "Witaj Piotrek"
Zamiast wysyłać pojedynczo maile wyślij jednego z ukrytymi odbiorcami
Tak treść maila jest spersonalizowana o parę zmiennych.
Ja bym stworzył jakąś buforową wartość w bazie danych, gdzie skrypt wysyłający maile po każdym obiegu pętli uaktualniał postęp, z kolei z poziomu przeglądarki ajaxem sprawdzałbym jaka jest wartość postępu w bazie danych :)
Jeżeli mailing jest b.duży można uzupełnić pasek postępu o dodatkowe informacje typu ilość odrzuconych, odebranych czy też odczytanych maili.
Kiedyś napisałem skrypt który wysyłał pakiety mailingowe po 2-3 miesiące, i tak to rozwiązałem.
Wypróbuj to:
<?php
// Wszystko poza blokiem TWÓJ KOD edytujesz na własną odpowiedzialność :P
$recipients = array_fill(0, 50, 'foo@bar.com');
$total = count($recipients);
foreach ($recipients as $index => $recipient) {
// ustawiamy konieczne headery
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
// ---------- TWÓJ KOD START -----------
// imitujemy wysyłanie maila
sleep(1);
// tutaj wrzucasz to co chcesz przesłać na front-end
$data = json_encode([
'last_recipient' => $recipient,
'done' => $index + 1,
'total' => $total
]);
// ---------- TWÓJ KOD END -----------
// ten format musi być dokładnie taki
echo "data: " . $data . PHP_EOL;
echo PHP_EOL;
// tutaj musimy wywołać dokładnie te funkcje,
// w tej kolejności bo inaczej nie zadziala
ob_end_flush();
flush();
}
<span id="progress"></span>
<button id="send">Wyślij</button>
const sendBtn = document.getElementById('send')
sendBtn.addEventListener('click', function (e) {
const progress = document.getElementById('progress')
const sse = new EventSource('mail.php')
sse.addEventListener('message', function(e) {
const data = JSON.parse(e.data)
console.log(data);
progress.innerHTML = `${data.done}/${data.total}`
}, false)
})
Natknąłem się na coś takiego Desu. Dzieki, wyprobuję.
Moja wysylka trwa tyle bo co x czasu (konfigurowalne) robie chwilkę przerwy.