Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > it.comp.www.php > #22091 > unrolled thread
| Started by | Umberto Salsi <salsi@icosaedro.it> |
|---|---|
| First post | 2018-06-12 13:16 +0200 |
| Last post | 2018-06-18 12:05 +0200 |
| Articles | 4 — 2 participants |
Back to article view | Back to it.comp.www.php
mail() fallisce solo se tutti i destinatari vengono respinti? Umberto Salsi <salsi@icosaedro.it> - 2018-06-12 13:16 +0200
Re: mail() fallisce solo se tutti i destinatari vengono respinti? Alessandro Pellizzari <shuriken@amiran.it> - 2018-06-12 12:35 +0100
Re: mail() fallisce solo se tutti i destinatari vengono respinti? Umberto Salsi <salsi@icosaedro.it> - 2018-06-13 11:24 +0200
Re: mail() fallisce solo se tutti i destinatari vengono respinti? Umberto Salsi <salsi@icosaedro.it> - 2018-06-18 12:05 +0200
| From | Umberto Salsi <salsi@icosaedro.it> |
|---|---|
| Date | 2018-06-12 13:16 +0200 |
| Subject | mail() fallisce solo se tutti i destinatari vengono respinti? |
| Message-ID | <pfoa20$66j$1@gioia.aioe.org> |
Sto esplorando l'affidabilità di mail() per l'invio "massivo" a due o
più destinatari. Sebbene il manuale non lo dica, sembra che:
1. Non si può avere retroazione del motivo del fallimento.
2. Se fallisce, nessun messaggio viene inviato.
3. Sa ha successo, QUALCUNO dei destinatari potrebbe ricevere il
messaggio.
4. Se c'è un solo destinatario (To, Cc e Bcc) e questo viene respinto
dal server SMTP, allora mail() fallisce.
5. Se ci sono due o più destinatari (To, Cc e Bcc) e almeno uno di
questi viene accettato, allora mail() ha successo; non c'è modo di
sapere quali destinatari sono stati respinti se non andando a vedere i
log files del server o aspettanto i bounce.
Test code minimalista delle varie combinazioni che compila il campo To
(ma con Cc e Bcc sembra che le cose vadano nello stesso modo):
<?php
error_reporting(-1);
echo "PHP version: ", PHP_VERSION, "\n";
$good = "test@icosaedro.it";
$bad = "<<<>>>";
$unknown = "DoesNotExist@DoesNotExists";
$attempts = [
$good,
$bad,
$unknown,
"$good, $bad",
"$good, $unknown",
"$bad, $unknown"
];
foreach($attempts as $to){
echo "Sending to $to:\n";
var_dump( mail($to, "This message sent to $to", "Testing.") );
var_dump( error_get_last() );
}
?>
Esito del codice precedente, commentato:
PHP version: 7.2.4
Sending to test@icosaedro.it:
bool(true) {atteso}
NULL
Sending to <<<>>>:
bool(false) {atteso}
NULL {peccato che non si abbia il motivo del fallimento}
Sending to DoesNotExist@DoesNotExists:
bool(true) {evidentemente il mio SMTP non fa una verifica dominio preventiva, ok}
NULL
Sending to test@icosaedro.it, <<<>>>:
bool(true) {inaspettato, ma il primo destinatario riceve}
NULL
Sending to test@icosaedro.it, DoesNotExist@DoesNotExists:
bool(true) {a questo punto è il risultato atteso}
NULL
Sending to <<<>>>, DoesNotExist@DoesNotExists:
bool(true) {a questo punto, esito atteso}
NULL
You have new mail in /var/mail/test {sono arrivati i bounce!}
Sto cercando di irrobustire il metodo di trasporto mail() di PHPMailer,
ma senza successo.
Sono corrette le mie deduzioni?
C'è un altro modo di sapere perché mail() fallisce?
O bisogna proprio inviare un email alla volta?
Ciao,
___
/_|_\ Umberto Salsi
\/_\/ www.icosaedro.it
[toc] | [next] | [standalone]
| From | Alessandro Pellizzari <shuriken@amiran.it> |
|---|---|
| Date | 2018-06-12 12:35 +0100 |
| Message-ID | <fo9pfiF2rn5U1@mid.individual.net> |
| In reply to | #22091 |
On 12/06/2018 12:16, Umberto Salsi wrote: > Sto esplorando l'affidabilità di mail() per l'invio "massivo" a due o > più destinatari. Sebbene il manuale non lo dica, sembra che: Dipende tutto dal server mail sottostante. mail() non fa altro che accodare una mail nel server SMTP che hai configurato. In Windows mi pare lo faccia via SMTP stesso, mentre in Linux chiama il binario di sendmail (o l'equivalente fornito da postfix. Non so come funzioni per exim). Cosa succede poi dipende tutto da quello. Se il binario/SMTP invocato torna un codice di errore che mail() riconosce, puoi avere un minimo di feedback, altrimenti è semplicemente "fire and forget". L'unico modo di irrobustirlo è di non usare mail(), ma di implementare un client SMTP e gestire la comunicazione col server, cosa che mi pare Zend Mail e altre librerie fanno. Bye.
[toc] | [prev] | [next] | [standalone]
| From | Umberto Salsi <salsi@icosaedro.it> |
|---|---|
| Date | 2018-06-13 11:24 +0200 |
| Message-ID | <pfqnsr$6uq$1@gioia.aioe.org> |
| In reply to | #22092 |
Alessandro Pellizzari <shuriken@amiran.it> wrote: > Dipende tutto dal server mail sottostante. > > mail() non fa altro che accodare una mail nel server SMTP che hai > configurato. In Windows mi pare lo faccia via SMTP stesso, mentre in > Linux chiama il binario di sendmail (o l'equivalente fornito da postfix. > Non so come funzioni per exim). Con exim se invio a un solo destinatario e il suo indirizzo viene respinto dal server, mail() fallisce e tutto va bene. Invece, se ci sono 2 o più destinatari dove almeno uno viene accettato, allora mail() ha successo e io non sò quali sono stati accettati e quali no; fortunatamente exim ritorna in bounce sia gli indirizzi respinti, sia gli invii che sono falliti per altri motivi, ma temo che la cosa dipenda dal server specifico e dalla sua configurazione. Morale: con mail() bisogna inviare a un solo destinatario alla volta perché non è garantito che vengano poi segnalati gli indirizzi respinti in bounce. > Cosa succede poi dipende tutto da quello. > > Se il binario/SMTP invocato torna un codice di errore che mail() > riconosce, puoi avere un minimo di feedback, altrimenti è semplicemente > "fire and forget". > > L'unico modo di irrobustirlo è di non usare mail(), ma di implementare > un client SMTP e gestire la comunicazione col server, cosa che mi pare > Zend Mail e altre librerie fanno. Sto mettendo mano alla mia implementazione di PHPMailer, che supporta diversi metodi di trasporto, incluso SMTP, sendmail/qmail. Il metodo mail() sembra il meno raccomandabile. Per sendmail/qmail sto cercando di catturare qualche feedback dai processi; si vedrà. Ciao, ___ /_|_\ Umberto Salsi \/_\/ www.icosaedro.it
[toc] | [prev] | [next] | [standalone]
| From | Umberto Salsi <salsi@icosaedro.it> |
|---|---|
| Date | 2018-06-18 12:05 +0200 |
| Message-ID | <pg8051$1t1u$1@gioia.aioe.org> |
| In reply to | #22091 |
Umberto Salsi <salsi@icosaedro.it> wrote: > Sto esplorando l'affidabilità di mail() per l'invio "massivo" a due o > più destinatari. Sebbene il manuale non lo dica, sembra che: > > 1. Non si può avere retroazione del motivo del fallimento. Aggiornamenti sulla mia indagine: Sembra che qualcuno sia riuscito ad ottenere il motivo del fallimento di mail() andando a guardare l'ultimo errore generato con error_get_last()['message']), ma non è chiaro il contesto di questi casi; a me risulta invece che non viene mai settato, e neppure mail() genera E_WARNING per cui non c'è nessun errore da gestire. Ho scoperto che in realtà qualche retroazione si può ottenere sfruttando il parametro opzionale di mail() che consente di impostare opzioni custom. L'effetto di queste opzioni dipende dallo specifico processo "sendmail" usato. Per esempio, con Exim e Sendmail si può mettere "-oep -oeq -oi" per cui mail() ha sempre successo anche se alcuni destinatari vengono respinti e anche se il messaggio è formalmente sbagliato (cioè non rispetta il formato RFC822); in tali casi: - l'errore viene loggato da sendmail nello stderr e quindi va a finire nel log degli errori del server; - il messaggio non viene inviato a nessun destinatario, neanche quelli validi; - nessun bounce viene generato. Ne segue che il programma non ha più retroazione del fallimento, però rimane una traccia permanente nel log file del server e si riducono i fastidiosi bounce. Per avere retroazione dell'errore a livello del programma bisogna per forza usare direttamente il processo sendmail e catturarne lo stderr con la triade popen(), fwrite() e pclose(), una cosa abbastanza acrobatica che sto cercando di far fare a PHPMailer. L'ultima possibilità è ricorrere direttamente al protocollo SMTP perché solo questo dà il massimo controllo su quello che accade e permette di saper quali destinatari sono stati accettati e quali no, e sapere se alla fine della fiera il messaggio è stato accettato per il recapito oppure no; anche questo sto cercando di curarlo in PHPMailer. Spero che possa tornare utile a qualcuno. Ciao, ___ /_|_\ Umberto Salsi \/_\/ www.icosaedro.it
[toc] | [prev] | [standalone]
Back to top | Article view | it.comp.www.php
csiph-web