Pregunta

Estoy un poco preocupado si esta función envía correos electrónicos que puedan ser reconocidos correctamente en la mayoría de los clientes de correo electrónico y webmail como debería, específicamente lo que más me preocupa son estas dudas:

  • ¿Están bien formadas las declaraciones y archivos adjuntos UTF-8?
  • ¿Necesito usar quoted_printable_decode()?¿Si sí donde?
  • Codificación de transferencia de contenido:¿7 u 8 bits?Siempre he visto 7, pero como envío un correo codificado en UTF-8, no estoy seguro.
  • ¿Debo usar mb_send_mail() o mail() es suficiente?

EDITAR:No sé por qué pero el código no aparece correctamente, lo puse a disposición @ http://gist.github.com/104818

EDITAR 2:Conozco otras alternativas (bibliotecas) para el manejo de correo electrónico, pero por 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;
}
¿Fue útil?

Solución

Si bien eso debería funcionar, recomiendo encarecidamente utilizar una clase de correo/SMTP prediseñada como Zend_Mail.Si bien no creo que todo Zend Framework sea el pijama del gato, tengo una muy buena opinión sobre su código de manejo de correo.

EDITAR:También debo agregar que el uso de una clase de correo/SMTP prediseñada abstraerá casi toda la complejidad/estructura de los correos electrónicos de varias partes.

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

  • ¿Están bien formadas las declaraciones y archivos adjuntos UTF-8?

Se ven bastante decentes.

  • ¿Necesito usar quoted_printable_decode()?¿Si sí donde?

No.querrías usar quoted_printable_decode() sólo si está decodificando un mensaje de correo electrónico.No cuando estás codificando uno.¿Deberías usar quoted_printable_encode()?Hablaré de esto a continuación.

  • Codificación de transferencia de contenido:¿7 u 8 bits?Siempre he visto 7, pero como envío un correo codificado en UTF-8, no estoy seguro.

Utilice únicamente codificación de 8 bits si sabe que el servidor SMTP de destino puede admitirla.Sin embargo, dado que está pasando 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 y CR y LF solo pueden aparecer como parte del final de línea CRLF (http://tools.ietf.org/html/rfc2045#section-2.7).

Le recomendaría que utilice Quoted-Printable (http://tools.ietf.org/html/rfc2045#section-6.7) Codificación-Transferencia-Contenido.donde estas llamando trim(strip_tags($message, '<a>')) y trim($message) querrás incluirlos con quoted_printable_encode(trim(...)).

  • ¿Debería usar mb_send_mail() o mail() ¿es suficiente?

si sabes que lo eres no manejará mensajes multibyte (japonés, coreano, chino, etc.) entonces mail() debería ser suficiente.

Ahora que he respondido a tus preguntas iniciales, déjame decirte dónde existen algunos problemas.

  1. Está especificando que el conjunto de caracteres de sus partes de contenido de texto sin formato y HTML es UTF-8, sin embargo, no aparece, ya que en realidad se está asegurando de que realmente estén codificados en UTF-8.
  2. estas comprobando null en $to, $bcc, $attachments Sin embargo, antes de seguir procesándolos, no estás haciendo nada cuando en realidad pueden estar null.Entonces, si recibes un null para $to, no procesas la variable, pero continúas enviando un correo electrónico a null.

Por ahora, eso es todo lo que voy a abordar, pero seguiré recomendando encarecidamente una solución prediseñada, ya que han tenido muchos usuarios y tiempo para solucionar errores.

Otros consejos

Estoy dispuesto a rodar por su cuenta en la mayoría de las situaciones, pero cuando se trata de correo, recomiendo encarecidamente que sea más fácil para usted y use algo como Swift Mailer o PHPMailer (en ese orden, por mi dinero) .

Como bonificación adicional (y suponiendo que especifique respuesta, etc.), también tiene muchas menos posibilidades de ser etiquetado como spam.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top