2015-09-23 18 views
6

Używam PHPMailer do wysyłania wiadomości e-mail, która działa świetnie. Problem polega jednak na tym, że ponieważ wysyła ona e-mail synchronicznie, kolejne ładowanie strony zajmuje dużo czasu.Wyślij e-mailem asynchronicznie przez PhpMailer

używam PHPMailer, jak pokazano w poniższym przykładzie https://github.com/PHPMailer/PHPMailer/blob/master/examples/gmail.phps

Zastanawiam się, czy istnieje sposób, aby dostawy email asynchronicznym. Badałem to i okazało się, że sendmail ma opcję, aby ustawić tryb „tła” DeliveryMode - źródło http://php.net/manual/en/function.mail.php

mail($to, $subject, $message, $headers, 'O DeliveryMode=b'); 

Chcę wiedzieć, czy coś podobnego można zrobić w PHPMailer? Czy ktoś miał z tym jakiś sukces?

EDIT: - (Informacje dodatkowe) Wydaje się PHPMailer może być skonfigurowany do korzystania z sendmail - https://github.com/PHPMailer/PHPMailer/blob/master/class.phpmailer.php Dlatego zastanawiam się, czy można to jakoś wykorzystała, aby umożliwić dostarczanie tła.

/** 
* Which method to use to send mail. 
* Options: "mail", "sendmail", or "smtp". 
* @type string 
*/ 
public $Mailer = 'mail'; 

/** 
* The path to the sendmail program. 
* @type string 
*/ 
public $Sendmail = '/usr/sbin/sendmail'; 
/** 
* Whether mail() uses a fully sendmail-compatible MTA. 
* One which supports sendmail's "-oi -f" options. 
* @type boolean 
*/ 
public $UseSendmailOptions = true; 

/** 
* Send messages using $Sendmail. 
* @return void 
*/ 
public function isSendmail() 
{ 
    $ini_sendmail_path = ini_get('sendmail_path'); 
    if (!stristr($ini_sendmail_path, 'sendmail')) { 
     $this->Sendmail = '/usr/sbin/sendmail'; 
    } else { 
     $this->Sendmail = $ini_sendmail_path; 
    } 
    $this->Mailer = 'sendmail'; 
} 

także - podobno istnieje sposób, aby ustawić opcje sendmail poprzez php.ini http://blog.oneiroi.co.uk/linux/php/php-mail-making-it-not-suck-using-sendmail/

wolałbym zrobić to jako argument na rolkach do wywołania API vs php.ini tak że existing globalnym zmiana. Czy ktoś próbował tego?

Odpowiedz

14

Niewłaściwe podejście.

PHPMailer nie jest serwerem pocztowym, o to pytasz. SMTP to gadatliwy, gadatliwy protokół, który jest podatny na opóźnienia i niską przepustowość, i zupełnie nie nadaje się do wysyłania interaktywnego podczas typowego przesyłania stron internetowych (z czym prawdopodobnie związane jest pytanie związane z BlackHatSamurai). Wielu ucieka od robienia właśnie tego, ale nie dajcie się zwieść myśleniu, że to dobre rozwiązanie i zdecydowanie nie próbujcie implementować MTA.

Przykład gmail, z którym się łączysz, używa SMTP do zdalnego serwera, który zawsze będzie wolniejszy niż przesyłanie lokalnie. Jeśli przesyłasz za pośrednictwem sendmaila (lub mail() - to w zasadzie to samo) do lokalnego serwera i zajmuje to więcej niż około 0,1 s, robisz coś bardzo nie tak. Nawet SMTP do localhosta nie potrwa dłużej, a wysyłanie do pobliskiego hosta nie powinno być zbyt wolne.

Próbowanie tła za pomocą wątków jest ogromną puszką robaków, co nie jest właściwym sposobem na osiągnięcie tego celu - cokolwiek osiągniesz w ten sposób, byłoby okropne w porównaniu do właściwego serwera pocztowego. Po prostu tego nie rób.

Odpowiednim sposobem jest zainstalowanie lokalnego serwera poczty i przesłanie do niego wiadomości za pomocą PHPMailer. Ta metoda jest bardzo szybka (setki wiadomości na sekundę), i musisz zrobić dokładnie nic, czego nie można uzyskać pod, ponieważ tak działa PHPMailer domyślnie.

Serwer pocztowy zrobi to, co powinien - umieści w kolejce wiadomość, poradzi sobie z problemami z połączeniem, odroczeniami dostawy, odrzuceniami i wszystkim, o czym nie myślisz.

+0

Fantastyczna odpowiedź. Dzięki za szczegółowe wyjaśnienie. Bardzo doceniane !! Jestem trochę noobem, jeśli chodzi o ten temat - czy masz jakieś zalecenia, na które serwer poczty wybrać/zainstalować. Jestem na wspólnym planie hostingu. Nie jestem pewien, czy mój serwer pozwoli mi zainstalować niestandardowy. – rogerb

+0

Większość dystrybucji linuksa używa postfiksu, który wolę eximować. Jest jednak dużo innych. Jeśli twój ISP nie pozwoli ci go zainstalować, prawdopodobnie dostarczy coś już, lub pobliski host - sprawdź ich dokumenty, otwórz bilet wsparcia. Jeśli nie, proponuję zainstalować nowego dostawcę usług ... – Synchro

+1

Dzięki @Synchro. Skończyło się na używaniu domyślnego serwera pocztowego dostarczonego przez mojego dostawcę usług hostingowych i zauważyłem (z sygnaturą czasową), że trwało to około 2 s na e-mail. Więc zadzwoniłem do mojego hosta i powiedzieli, że skoro byłem na wspólnym planie hostingu, oczekiwano tego opóźnienia (najwyraźniej ich serwer pocztowy wysyła do serwera proxy, gdzie czekał w kolejce przed wysłaniem). Wreszcie ustawiłem "-O DeliveryMode = b" w moim php.ini (http://blog.oneiroi.co.uk/linux/php/php-mail-making-it-not-suck-using-sendmail/), który zrobił OGROMNĄ różnicę. E-maile są teraz wysyłane w tle, a mój skrypt zwraca się w ciągu ** 0,16 s! ** – rogerb

0

Zgodnie z thisphpMailer nie obsługuje tego typu połączenia. Trzeba by napisać własną klasę z wątkami, aby wykonać wywołanie asynchroniczne. Zobacz klasę pThreads i Thread. Znaleziono jeszcze jedno rozwiązanie: here.

+0

Dziękujemy za odpowiedź i linki. Zastanawiam się, czy jest to całkowicie dokładne (do daty), ponieważ phpMailer wydaje się pozwalać sendmailowi ​​jako mechanizmowi dostarczania. Zmienię moje pytanie i dodaję do niego te informacje. – rogerb

+0

@rogerb, niezależnie musiałbyś przerobić klasę Sendmail, aby użyć wątku asynchronicznego. – BlackHatSamurai

+0

Co powiesz na używanie hosta inteligentnego? – Phil