2009-05-01 29 views
16

tôi là một chút lo lắng nếu chức năng này sẽ gửi email có thể được công nhận một cách chính xác trên phần lớn các email và webmail khách hàng một cách cần, đặc biệt tôi quan tâm nhất về vấn đề này nghi ngờ:Đây có phải là cách chính xác để gửi email bằng PHP không?

  • Are UTF -8 tờ khai và chấp trước được hình thành tốt?
  • Tôi có cần sử dụng quoted_printable_decode() không? Nếu có, ở đâu?
  • Content-Transfer-Encoding: 7 hoặc 8 bit? Tôi đã luôn luôn nhìn thấy 7 nhưng kể từ khi tôi đang gửi một thư được mã hóa UTF-8 tôi không chắc chắn.
  • Tôi có nên sử dụng mb_send_mail() hoặc thư() là đủ?

EDIT: Tôi không biết tại sao nhưng mã không hiển thị đúng, tôi đã làm cho nó có sẵn @http://gist.github.com/104818

EDIT 2: Tôi nhận thức được lựa chọn thay thế khác (thư viện) cho xử lý email, nhưng vì lợi ích của sự tò mò và kiến ​​thức của riêng tôi, tôi chỉ muốn biết liệu mã này có tốt hay không, hoặc nếu nó có lỗi.

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

Trả lời

27

Trong khi đó nên làm việc, tôi sẽ khuyên bạn sử dụng một dựng sẵn Mail/lớp SMTP như Zend_Mail. Trong khi tôi không nghĩ rằng toàn bộ khung công tác Zend là bộ đồ ngủ của con mèo, tôi có một ý kiến ​​rất tốt về mã xử lý thư của họ.

CHỈNH SỬA: Tôi cũng nên thêm rằng sử dụng lớp Mail/SMTP dựng sẵn sẽ trừu tượng hầu như tất cả tính phức tạp/cấu trúc của email nhiều phần.

Cập nhật 2009-05-06: Trả lời trực tiếp câu hỏi của bạn.

  • Khai báo và đính kèm UTF-8 có được định dạng tốt không?

Chúng đủ phong nha.

  • Tôi có cần phải sử dụng quoted_printable_decode()? Nếu có, ở đâu?

số Bạn sẽ muốn sử dụng quoted_printable_decode() chỉ khi bạn đang giải mã một thông báo email. Không phải khi bạn đang mã hóa một. Bạn có nên sử dụng quoted_printable_encode() không? Tôi sẽ thảo luận điều này tiếp theo.

  • Content-Transfer-Encoding: 7 hoặc 8 bit? Tôi đã luôn luôn nhìn thấy 7 nhưng kể từ khi tôi đang gửi một thư được mã hóa UTF-8 tôi không chắc chắn.

Chỉ sử dụng mã hóa 8 bit nếu bạn biết máy chủ SMTP đích có thể hỗ trợ nó. Tuy nhiên, vì bạn đang chuyển email của mình sang MTA địa phương, tôi không khuyên bạn nên đặt giá trị này.Giá trị mặc định là mã hóa 7bit, nhưng nó có bộ hạn chế riêng: tối đa 998 octet trên mỗi dòng của phạm vi mã 1-127 với CR và LF chỉ được phép xuất hiện như một phần của dòng CRLF kết thúc (http://tools.ietf.org/html/rfc2045#section-2.7).

Tôi khuyên bạn nên sử dụng tính năng Chuyển mã nội dung có thể trích dẫn (http://tools.ietf.org/html/rfc2045#section-6.7). Trong trường hợp bạn đang gọi trim(strip_tags($message, '<a>'))trim($message), bạn sẽ muốn kèm theo những người đó với quoted_printable_encode(trim(...)).

  • Tôi có nên sử dụng mb_send_mail() hoặc mail() là đủ?

Nếu bạn biết bạn là không sẽ được xử lý thông điệp nhiều byte (Nhật Bản, Hàn Quốc, Trung Quốc, vv) sau đó mail() nên đủ.

Bây giờ tôi đã trả lời các câu hỏi ban đầu của bạn, hãy để tôi cho bạn biết một số vấn đề tồn tại.

  1. Bạn đang xác định rằng bộ Ký tự văn bản thuần tuý và phần nội dung Html là UTF-8, tuy nhiên nó không xuất hiện vì bạn thực sự đảm bảo rằng chúng thực sự được mã hóa UTF-8.
  2. Bạn đang kiểm tra null trong $to, $bcc, $attachments trước khi tiếp tục xử lý chúng, tuy nhiên, bạn không làm bất cứ điều gì khi chúng thực sự có thể là null. Vì vậy, nếu bạn tình cờ nhận được null cho $to, bạn không xử lý biến, nhưng bạn tiếp tục gửi email đến null.

Ngay bây giờ, đó là tất cả những gì tôi sẽ đi vào nhưng tôi vẫn sẽ đánh giá cao đề xuất giải pháp được tạo trước vì họ đã có rất nhiều người dùng/thời gian để khắc phục lỗi.

+0

Câu trả lời tốt đẫm máu Mr Jones. Tôi hy vọng bạn nhận được tiền thưởng +1 – da5id

+1

Tôi đồng ý, Zend_Mail có mọi thứ bạn cần và hơn thế nữa! Sử dụng thư viện được nhiều người phát triển, nó thường có ít lỗi hơn. – Kekoa

+0

"Nếu bạn biết bạn sẽ không xử lý các tin nhắn nhiều byte (tiếng Nhật, tiếng Hàn, tiếng Trung, v.v ...) thì thư() là đủ." - Thư nào trong các ngôn ngữ khác, như tiếng Đức, tiếng Pháp, tiếng Bồ Đào Nha và tiếng Tây Ban Nha? Mail() vẫn đủ? –

17

Tôi là tất cả vì bạn sở hữu trong hầu hết các trường hợp, nhưng khi nói đến thư, tôi khuyên bạn nên làm dễ dàng hơn cho bản thân và sử dụng một cái gì đó như Swift Mailer hoặc PHPMailer (theo thứ tự đó, tiền của tôi) .

Là phần thưởng phụ (và giả sử bạn chỉ định trả lời, v.v.), bạn cũng có ít cơ hội bị gắn thẻ là spam hơn.

+3

Hmm .. Tôi chưa bao giờ nghe nói về Swift Mailer, nhưng sau khi đọc qua tài liệu, tôi sẽ phải bắt đầu xem xét nó thay vì Zend_Mail. Cảm ơn bạn về thông tin. +1 –

+0

Có. Tôi thực sự có thể giới thiệu PHPMailer! Nó đã làm một công việc tuyệt vời nhiều lần cho tôi. – TheHippo

Các vấn đề liên quan