Domanda

Sono un po 'preoccupato se questa funzione invia e-mail che possono essere riconosciute correttamente sulla maggior parte dei client di posta elettronica e webmail come dovrebbe, in particolare sono più preoccupato per questi dubbi:

  • Le dichiarazioni e gli allegati UTF-8 sono ben formati?
  • Devo usare quoted_printable_decode ()? Se sì, dove?
  • Codifica trasferimento contenuto: 7 o 8 bit? Ho sempre visto 7 ma dato che sto inviando una mail codificata UTF-8 non sono sicuro.
  • Dovrei usare mb_send_mail () o mail () è abbastanza?

MODIFICA: non so perché ma il codice non viene visualizzato correttamente, l'ho reso disponibile @ http://gist.github.com/104818

MODIFICA 2: sono a conoscenza di altre alternative (librerie) per la gestione della posta elettronica, ma per motivi di curiosità e conoscenza desidero solo sapere se questo codice è buono al 100% o se è difettoso .

function Email($name, $from, $to, $subject, $message, $bcc = null, $attachments = null)
{
    ini_set('SMTP', 'localhost');
    ini_set('sendmail_from', $from);

    $name = filter_var($name, FILTER_SANITIZE_STRING);
    $from = filter_var($from, FILTER_SANITIZE_EMAIL);
    $subject = filter_var($subject, FILTER_SANITIZE_STRING);

    $boundary = '_Boundary_' . md5(microtime(true) . mt_rand(0, PHP_INT_MAX));

    $headers = array
    (
        'MIME-Version: 1.0',
        'Content-Type: multipart/mixed; boundary="Mixed' . $boundary . '"',
        'Date: ' . date('r', time()),
        'From: "' . $name . '" <' . $from . '>',
        'Reply-To: "' . $name . '" <' . $from . '>',
        'Return-Path: "' . $name . '" <' . $from . '>',
        'X-Mailer: PHP ' . phpversion(),
        'X-Priority: 2',
        'X-MSMail-Priority: High',
        'X-Originating-IP: ' . $_SERVER['SERVER_ADDR'],
    );

    if (is_null($to) === false)
    {
        if (is_array($to) === false)
        {
            $to = explode(',', $to);
        }

        foreach ($to as $key => $value)
        {
            $to[$key] = filter_var($value, FILTER_SANITIZE_EMAIL);
        }

        $to = implode(', ', array_filter($to));
    }

    if (is_null($bcc) === false)
    {
        if (is_array($bcc) === false)
        {
            $bcc = explode(',', $bcc);
        }

        foreach ($bcc as $key => $value)
        {
            $bcc[$key] = filter_var($value, FILTER_SANITIZE_EMAIL);
        }

        $headers[] = 'BCC: ' . implode(', ', array_filter($bcc));
    }

    if (is_null($attachments) === false)
    {
        settype($attachments, 'array');

        foreach ($attachments as $key => $value)
        {
            if (is_file($value) === true)
            {
                $attachments[$key] = array
                (
                    '',
                    '--Mixed' . $boundary,
                    'Content-Type: application/octet-stream; name="' . basename($value) . '"',
                    'Content-Disposition: attachment; filename="' . basename($value) . '"',
                    'Content-Transfer-Encoding: base64',
                    '',
                    trim(chunk_split(base64_encode(file_get_contents($value)))),
                );

                $attachments[$key] = implode("\n", $attachments[$key]);
            }

            else
            {
                unset($attachments[$key]);
            }
        }

        $attachments = implode("\n", $attachments) . "\n";
    }

    $message = array
    (
        'This is a multi-part message in MIME format.',
        '',
        '--Mixed' . $boundary,
        'Content-Type: multipart/alternative; boundary="Alt' . $boundary . '"',
        '',
        '--Alt' . $boundary,
        'Content-Type: text/plain; charset="UTF-8"',
        'Content-Disposition: inline',
        'Content-Transfer-Encoding: 8bit',
        '',
        trim(strip_tags($message, '<a>')),
        '',
        '--Alt' . $boundary,
        'Content-Type: text/html; charset="UTF-8"',
        'Content-Disposition: inline',
        'Content-Transfer-Encoding: 8bit',
        '',
        trim($message),
        '',
        '--Alt' . $boundary . '--',
        $attachments,
        '--Mixed' . $boundary . '--',
    );

    if (@mail($to, stripslashes($subject), implode("\n", $message), implode("\n", $headers)) === true)
    {
        return true;
    }

    return false;
}
È stato utile?

Soluzione

Anche se dovrebbe funzionare, consiglio vivamente di utilizzare una classe Mail / SMTP precompilata come Zend_Mail . Anche se non credo che l'intero Zend Framework sia il pigiama del gatto, ho un'ottima opinione del loro codice di gestione della posta.

EDIT: dovrei anche aggiungere che l'uso di una classe Mail / SMTP precompilata astrarrà quasi tutta la complessità / struttura delle e-mail in più parti.

Aggiornamento 2009-05-06: risposta diretta alla tua domanda.

  
      
  • Le dichiarazioni e gli allegati UTF-8 sono ben formati?
  •   

Sembrano abbastanza decenti.

  
      
  • Devo usare quoted_printable_decode()? Se sì, dove?
  •   

No. Si desidera utilizzare quoted_printable_encode() solo se si sta decodificando un messaggio e-mail. Non quando lo stai codificando. Dovresti usare trim(strip_tags($message, '<a>')) ? Ne discuterò dopo.

  
      
  • Codifica trasferimento contenuto: 7 o 8 bit? Ho sempre visto 7 ma dato che sto inviando una mail codificata UTF-8 non sono sicuro.
  •   

Utilizza la codifica a 8 bit solo se sai che il server SMTP di destinazione può supportarla. Tuttavia, poiché stai inviando la tua e-mail all'MTA locale, non consiglierei di impostare questo valore. Il valore predefinito è la codifica a 7 bit, ma ha un proprio set di restrizioni: fino a 998 ottetti per riga dell'intervallo di codice 1-127 con CR e LF ammessi solo come parte della fine della riga CRLF ( http://tools.ietf.org/html/rfc2045#section-2.7 ).

Ti consiglierei di usare Quoted-Printable ( http: //tools.ietf. org / html / rfc2045 # section-6.7 ) Codifica trasferimento-contenuto. Dove stai chiamando trim($message) e quoted_printable_encode(trim(...)) vorrai racchiudere quelli con mb_send_mail().

  
      
  • Devo usare mail() o null è abbastanza?
  •   

Se sai che non gestirai i messaggi Multibyte (giapponese, coreano, cinese, ecc.), $to dovrebbe bastare.

Ora che ho risposto alle tue domande iniziali, lascia che ti dica dove esistono alcuni problemi.

  1. Stai specificando che il set di caratteri delle tue parti di contenuto di testo semplice e HTML sono UTF-8, tuttavia non appare in quanto ti stai assicurando che siano realmente codificati UTF-8.
  2. Stai controllando $bcc in $attachments, <=>, <=> prima di elaborarli ulteriormente, tuttavia, non stai facendo nulla quando potrebbero effettivamente essere <=>. Quindi, se ti capita di ricevere un <=> per <=>, non elabori la variabile, ma continui a inviare un'email a <=>.

In questo momento, è tutto quello che ho intenzione di approfondire, ma continuerò a consigliare vivamente una soluzione pre-costruita poiché hanno avuto molti utenti / tempo per risolvere i bug.

Altri suggerimenti

Sono pronto per il roll-your-own nella maggior parte delle situazioni, ma quando si tratta di posta raccomanderei vivamente di semplificare te stesso e di usare qualcosa come Swift Mailer o PHPMailer (in questo ordine, per i miei soldi) .

Come bonus laterale (e supponendo che tu specifichi la risposta, ecc.), hai anche molte meno possibilità di essere taggato come spam.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top