Bülten gönderirken PHP aşımını önlemek

4 Cevap php

(Ben bahsetmeliyiz .. Geçenlerde Swiftmailer kütüphanesi hayata geçirdik, ama sadece yaklaşık 300 kişiye postalar göndermek zorunda olsa ben kullandım ilk kez, ben bir php zaman aşımı hatası var olduğunu kullanılarak set_time_limit(0); geçici) nedeniyle sunucu üzerinde kısıtlamalar için bir seçenek değil

Bunu kullanmak yolu şöyle:

 $transport = Swift_SmtpTransport::newInstance('smtp.mydomain.com',25);
 $mailer = Swift_Mailer::newInstance($transport);
 $message = Swift_Message::newInstance();
 $message->setSubject($_POST['subj']);
 $message->setFrom(array('email' => 'Mysite'));
 $message->setTo($recipients);
 $message->setBody(strip_tags($messagebody));
 $message->addPart($messagebody, 'text/html');
 $numSent = $mailer->batchSend($message);
 printf("Sent %d messages\n", $numSent);

$recipients (mySQL sorgu explode() ile inşa) e-postaların bir commaseparateddir dizisi nerede ..

Hiçbir fikrim komut zaman aşımı üretir Yukarıdaki kod parçası var, ve ben bir bülten işlev için kullanabilirsiniz beri bana bunu test veya hata ayıklama için, bu oldukça zordur, bu yüzden kimse ile geliyor gerçekten müteşekkir olacaktır Bu soruna bir (yakınında), kurşun geçirmez çözeltisi :)

Şimdiden teşekkürler!

Lars

4 Cevap

Eğer cron erişiminiz varsa, postaların düşük bir sayı işleme komut dosyası çalıştıran bir cron işi kullanarak kuyruğunu pop o zaman, haber bülteni göndermek için gereken ne bir veri tabanı doldurmak.

Eğer yoksa o ölüyor, sonra parametre olarak bir sonraki bülten geçen, kendini diyoruz böylece, senaryonun sonunda bir sistem () deyimi yazın. Eğer bir mail göndermek gerekir gibi Yani komut dosyası gibi çok zaman yürütmek olacaktır.

Posta gönderirken başına alıcı sayısını sınırlayın. Kıvrılma veya cron üzerinden offset değeri ile komut dosyası "n" defa çağırmak ve zaman aşımı atmak olmaz. . Örneğin set $ = 20 sınırı Sonra komut n kere çağırır:

send.php?offset=0
send.php?offset=20

(send.php komut dosyası çağırır) kök komut dosyası zaman aşımı olacaktır ve böylece ..., o zaman size son ofset postalar göndermeye devam edebilirsiniz.

[Güncelleme] çok altında veri benim dev kutusundan smtp sunucu dediğin için. Yani Doğu Avrupa iyi bir ev ADSL ABD SMTP sunucusuna (benim proje Sahneleme sunucusu). Tüm Sahneleme çalıştığında - yani localhost php + mysql + Postfix bu bebek ancak 30 alıcıya 5 ayrı e-posta ve BCC göndermek için 1 saniye sürer. Oldukça bir manzara ...

Swiftmaieler aslında eşzamanlı davranır ve başarısız posta Addys ile dizi alır, böylece her e-posta göndermek için SMTP sunucusu için bekler. Yani u BCC 100 alıcılara toplam süre ise: süresi 100 e-postalar göndermek için sunucu için sunucuya + zaman konuşmak götürüldü. 100 ayrı e-posta göndererek 100 * (konuşma süresi + gönderme saati) olacaktır. Benim Postfix e-posta başına 1 saniye sürer ve tek bir e-posta göndermek için 2.5 saniye sürer bu yüzden konuşma süresi de 1 sn. Standart 30 sn zaman aşımı sayesinde BCC 12 bireysel e-postalar veya 20 alıcıları olacaktır. Aslında hepsi bir tahmin oyunu: P

Tüm bu mailler hve bir zorunluluk olarak set_time_limit (0) ile tasarlanmış gibi görünüyor. Yöntem, her x - 30 saniye zaman aşımı olan birisi için akıllı yol açık kalır ve bir ifrme + yenileme veya "send mail paket" (10 küçük bir) çağırır Ajax mekanizması vardır sayfasında bir "gönderme toplu" sahip olacaktır saniye. Ajax ile komut yanıt tekrar diyebiliriz.

set_time_limit(0); kodundan önce

EDIT: Eğer set_time_limit () fonksiyonunu kullanamazsınız çünkü Peki, neden bir işlevin içinde e-posta gönderir kodu koymak değil ve register_shutdown_function (?) Bunun dışında komut kez tekrar işlevini dediğimiz yol,.