2009-05-01 3 views
16

Я немного волнуется, если эта функция отправляет сообщения электронной почты, которые могут быть распознаны правильно на большинстве электронных и почтовых клиентов, как это должно, в частности, я больше всего обеспокоен этим сомневается:Правильно ли вы отправляете электронную почту с помощью PHP?

  • Является UTF -8 деклараций и вложений хорошо сформированы?
  • Нужно ли использовать quoted_printable_decode()? Если да, то где?
  • Content-Transfer-Encoding: 7 или 8 бит? Я всегда видел 7, но поскольку я отправляю кодированную почту UTF-8, я не уверен.
  • Должен ли я использовать mb_send_mail() или mail() достаточно?

EDIT: Я не знаю, почему, но код не отображается правильно, я сделал его доступным @http://gist.github.com/104818

EDIT 2: Я знаю о других альтернативах (библиотеки) для электронная почта, но ради моего любопытства и знаний я просто хочу знать, является ли этот код на 100% хорошим, или если он глючит.

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

ответ

27

Хотя это должно работать, я бы настоятельно рекомендовал использовать прекомпилированный Mail/SMTP класс, такие как Zend_Mail. Хотя я не думаю, что вся Zend Framework является пижамой кошки, у меня есть очень хорошее мнение об их почтовом коде.

EDIT: Я также должен добавить, что использование предварительно созданного класса Mail/SMTP абстрагирует почти всю сложность/структуру многочастных электронных писем.

Обновление 2009-05-06: Ответ на ваш вопрос напрямую.

  • ли UTF-8 декларации и вложения хорошо сформированы?

Они выглядят достаточно прилично.

  • мне нужно использовать quoted_printable_decode() ли? Если да, то где?

Нет, вы хотели бы использовать quoted_printable_decode() только если декодирование сообщения электронной почты. Не когда вы его кодируете. Следует ли использовать quoted_printable_encode()? Я расскажу об этом дальше.

  • Content-Transfer-Encoding: 7 или 8 бит? Я всегда видел 7, но поскольку я отправляю кодированную почту UTF-8, я не уверен.

используется кодировка 8bit только если вы знаете, что целевой сервер SMTP может поддерживать его. Однако, поскольку вы отправляете свою электронную почту в местный MTA, я бы не рекомендовал устанавливать это значение.Значение по умолчанию - 7-битное кодирование, но у него есть собственный набор ограничений: до 998 октетов на строку диапазона кода 1-127 с CR и LF разрешено появляться как часть окончания строки CRLF (http://tools.ietf.org/html/rfc2045#section-2.7).

Я бы порекомендовал вам использовать кодировку Content-Transfer-кодирование (http://tools.ietf.org/html/rfc2045#section-6.7). Когда вы звоните trim(strip_tags($message, '<a>')) и trim($message), вам необходимо приложить их к quoted_printable_encode(trim(...)).

  • Должен ли я использовать mb_send_mail() или mail() достаточно?

Если вы знаете, что вы не будет обработку сообщений многобайтных (японский, корейский, китайский и т.д.), то mail() должно хватить.

Теперь, когда я ответил на ваши начальные вопросы, позвольте мне рассказать вам, где существуют некоторые проблемы.

  1. Вы указываете, что набор символов вашего обычного текста и Html части контента являются UTF-8, однако он не появляется, как вы на самом деле гарантируя, что они действительно являются UTF-8 закодирован.
  2. Вы проверки null в $to, $bcc, $attachments прежде чем дальше обрабатывать их, тем не менее, вы ничего не делаете, когда они могут быть на самом деле null. Итак, если вы случайно получили null для $to, вы не обрабатываете эту переменную, но продолжаете отправлять письмо по адресу null.

Как сейчас, это все, что я собираюсь войти, но я по-прежнему очень рекомендую готовое решение, так как у них было много пользователей/время для разработки ошибок.

+0

Кровавый хороший ответ Г-н Джонс. Надеюсь, ты получишь щедрость +1 – da5id

+1

Согласен, у Zend_Mail есть все, что вам нужно, и многое другое! Используйте библиотеку, разработанную многими людьми, она обычно имеет меньше ошибок. – Kekoa

+0

«Если вы знаете, что не собираетесь обрабатывать сообщения Multibyte (японский, корейский, китайский и т. Д.), Тогда mail() должно быть достаточно». - Какие сообщения на других языках, например, на немецком, французском, португальском и испанском языках? Достаточно ли почты()? –

17

В большинстве случаев я использую для вашего собственного общения, но когда дело доходит до почты, я бы сердечно рекомендовал облегчить себе и использовать что-то вроде Swift Mailer или PHPMailer (в этом порядке за мои деньги) ,

В качестве бонусного бонуса (и если вы укажете ответ на и т. Д.), У вас также будет гораздо меньше шансов быть помеченным как спам.

+3

Хм .. Я никогда не слышал о Swift Mailer, но, прочитав документацию, мне придется начать рассматривать его вместо Zend_Mail. Спасибо за информацию. +1 –

+0

Да. Я действительно мог бы рекомендовать PHPMailer! Для меня это было много раз. – TheHippo