2009-05-01 21 views
16

estoy un poco preocupado si esta función envía mensajes de correo electrónico que pueden ser reconocidos correctamente en la mayoría de los clientes de correo electrónico y correo web como debe, específicamente estoy más preocupado por esta duda:¿Es esta la forma correcta de enviar correos electrónicos con PHP?

  • son el UTF -8 declaraciones y archivos adjuntos bien formados?
  • ¿Debo usar quoted_printable_decode()? ¿Si sí donde?
  • Content-Transfer-Encoding: 7 u 8 bits? Siempre he visto 7 pero desde que estoy enviando un correo codificado en UTF-8 no estoy seguro.
  • ¿Debo usar mb_send_mail() o mail() es suficiente?

EDIT: no sé por qué, pero el código no aparece correctamente, lo hice disponibles @http://gist.github.com/104818

EDIT 2: Soy consciente de otras alternativas (bibliotecas) para manejo de correo electrónico, pero por el bien de mi propia curiosidad y conocimiento solo deseo saber si este código es 100% bueno, o si tiene errores.

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; 
} 

Respuesta

27

Mientras que debería funcionar, recomendaría encarecidamente el uso de una clase de pre-compilados de correo/SMTP como Zend_Mail. Si bien no creo que todo el Zend Framework sea el pijama del gato, sí tengo una muy buena opinión del código de manejo de correo.

EDITAR: También debo agregar que el uso de una clase precompilada de Correo/SMTP resumirá casi toda la complejidad/estructura de los correos electrónicos de varias partes.

Actualización 2009-05-06: Respondiendo a su pregunta directamente.

  • son los caracteres UTF-8 declaraciones y archivos adjuntos bien formados?

Se ven lo suficientemente decentes.

  • ¿Es necesario utilizar quoted_printable_decode()? ¿Si sí donde?

No. Usted desea utilizar quoted_printable_decode() sólo si está decodificando un mensaje de correo electrónico. No cuando estás codificando uno. ¿Debería usar quoted_printable_encode()? Discutiré esto el próximo.

  • Content-Transfer-Encoding: 7 u 8 bits? Siempre he visto 7 pero desde que estoy enviando un correo codificado en UTF-8 no estoy seguro.

Utilice sólo 8 bits de codificación si se sabe que el servidor SMTP de destino, puede apoyarla. Sin embargo, dado que está enviando su correo electrónico al MTA local, no recomendaría establecer este valor.El valor predeterminado es la codificación de 7 bits, pero tiene su propio conjunto de restricciones: hasta 998 octetos por línea del rango de código 1-127 con CR y LF solo permitido aparecer como parte de la terminación de línea CRLF (http://tools.ietf.org/html/rfc2045#section-2.7).

Yo recomendaría que utilice la Quoted-Printable (http://tools.ietf.org/html/rfc2045#section-6.7) Content-Transfer-Encoding. Cuando llame al trim(strip_tags($message, '<a>')) y trim($message), deberá adjuntar los que tengan quoted_printable_encode(trim(...)).

  • Debo utilizar mb_send_mail() o mail() es suficiente?

Si usted sabe que está no va a manejar los mensajes de varios bytes (japoneses, coreanos, chinos, etc.), entonces mail() debería ser suficiente.

Ahora que he respondido a sus preguntas iniciales, déjeme decirle dónde existen algunos problemas.

  1. Usted está especificando que el juego de caracteres del texto sin formato y piezas de contenido HTML son UTF-8, sin embargo, no parece que en realidad se está asegurando de que lo que realmente son codificación UTF-8.
  2. está comprobando las null en $to, $bcc, $attachments antes de procesarlos más, sin embargo, usted no está haciendo nada cuando en realidad pueden ser null. Por lo tanto, si recibe un null para $to, no procesa la variable, pero continúa enviando un correo electrónico al null.

A partir de ahora, eso es todo lo que voy a entrar, pero aún voy a recomendar una solución preconstruida, ya que han tenido muchos usuarios/tiempo para resolver errores.

+0

Sangrienta buena respuesta Sr. Jones. Espero que recibas la recompensa +1 – da5id

+1

¡Estoy de acuerdo, Zend_Mail tiene todo lo que necesitas y más! Use una biblioteca desarrollada por muchas personas, generalmente tiene menos errores. – Kekoa

+0

"Si sabe que no va a manejar mensajes de Multibyte (japonés, coreano, chino, etc.), entonces mail() debería ser suficiente". - ¿Qué mensajes en otros idiomas, como alemán, francés, portugués y español? ¿Mail() todavía es suficiente? –

17

Soy todo para rodar su propios en la mayoría de las situaciones, pero cuando se trata de un correo electrónico que me recomiendo por lo que es más fácil para ti y usar algo como Swift Mailer o PHPMailer (en ese orden, por mi dinero) .

Como bonificación lateral (y suponiendo que especifiques la respuesta, etc.), también tienes muchas menos posibilidades de ser etiquetado como correo no deseado.

+3

Hmm .. Nunca he oído hablar de Swift Mailer, pero después de leer toda la documentación, voy a tener que empezar a considerarlo en lugar de Zend_Mail. Gracias por la info. +1 –

+0

Sí. ¡Realmente podría recomendar PHPMailer! Hizo un gran trabajo muchas veces para mí. – TheHippo

Cuestiones relacionadas