Mặc dù có những phần của câu trả lời này chỉ áp dụng cho việc sử dụng mail()
hàm, nhưng nhiều bước khắc phục sự cố này có thể được áp dụng cho bất kỳ hệ thống gửi thư PHP nào.
Có nhiều lý do khiến tập lệnh của bạn dường như không gửi email. Thật khó để chẩn đoán những điều này trừ khi có lỗi cú pháp rõ ràng. Không có ai bạn cần phải chạy qua danh sách kiểm tra bên dưới để tìm bất kỳ cạm bẫy tiềm năng nào bạn có thể gặp phải.
Đảm bảo báo cáo lỗi được bật và được đặt thành báo cáo tất cả các lỗi
Báo cáo lỗi là điều cần thiết để loại bỏ các lỗi trong mã của bạn và các lỗi chung mà PHP gặp phải. Báo cáo lỗi cần phải được kích hoạt để nhận được các lỗi này. Đặt mã sau vào đầu tệp PHP của bạn (hoặc trong tệp cấu hình chính) sẽ cho phép báo cáo lỗi.
error_reporting(-1);
ini_set('display_errors', 'On');
set_error_handler("var_dump");
Xem Làm thế nào tôi có thể nhận được thông báo lỗi hữu ích trong PHP? - câu trả lời này để biết thêm chi tiết về điều này.
Hãy chắc chắn rằng mail()
hàm được gọi
Nó có vẻ ngớ ngẩn nhưng một lỗi phổ biến là quên thực sự đặt mail()
hàm trong mã của bạn. Hãy chắc chắn rằng nó ở đó và không bình luận ra.
Hãy chắc chắn rằng mail()
hàm được gọi đúng
thư bool (chuỗi $ đến, chuỗi $ chủ đề, chuỗi $ message [, chuỗi $ thêm_headers [, chuỗi $ thêm_parameter]])
Hàm mail có ba tham số bắt buộc và tùy chọn thứ tư và thứ năm. Nếu cuộc gọi của bạn mail()
không có ít nhất ba tham số thì nó sẽ thất bại.
Nếu cuộc gọi của bạn mail()
không có các tham số chính xác theo đúng thứ tự thì nó cũng sẽ thất bại.
Kiểm tra nhật ký thư của máy chủ
Máy chủ web của bạn sẽ đăng nhập tất cả các nỗ lực để gửi email thông qua nó. Vị trí của các nhật ký này sẽ khác nhau (bạn có thể cần hỏi quản trị viên máy chủ của mình nơi chúng được đặt) nhưng chúng thường có thể được tìm thấy trong thư mục gốc của người dùng bên dưới logs
. Bên trong sẽ có thông báo lỗi mà máy chủ báo cáo, nếu có, liên quan đến nỗ lực gửi email của bạn.
Kiểm tra lỗi kết nối cổng
Khối cổng là một vấn đề rất phổ biến mà hầu hết các nhà phát triển phải đối mặt trong khi tích hợp mã của họ để gửi email bằng cách sử dụng SMTP. Và, điều này có thể dễ dàng truy tìm tại các maillogs của máy chủ (vị trí của máy chủ của nhật ký thư có thể thay đổi từ máy chủ này sang máy chủ khác, như đã giải thích ở trên). Trong trường hợp bạn đang ở trên một máy chủ lưu trữ được chia sẻ, các cổng 25 và 587 vẫn bị chặn theo mặc định. Khối này được cố tình thực hiện bởi nhà cung cấp dịch vụ lưu trữ của bạn. Điều này đúng ngay cả đối với một số máy chủ chuyên dụng. Khi các cổng này bị chặn, hãy thử kết nối bằng cổng 2525. Nếu bạn thấy cổng đó cũng bị chặn, thì giải pháp duy nhất là liên hệ với nhà cung cấp dịch vụ lưu trữ của bạn để bỏ chặn các cổng này.
Hầu hết các nhà cung cấp dịch vụ lưu trữ đều chặn các cổng email này để bảo vệ mạng của họ gửi bất kỳ email spam nào.
Sử dụng cổng 25 hoặc 587 cho kết nối trơn / TLS và cổng 465 cho kết nối SSL. Đối với hầu hết người dùng, nên sử dụng cổng 587 để tránh giới hạn tốc độ do một số nhà cung cấp dịch vụ lưu trữ đặt ra.
Không sử dụng toán tử triệt tiêu lỗi
Khi toán tử triệt tiêu lỗi @
được thêm vào một biểu thức trong PHP, mọi thông báo lỗi có thể được tạo bởi biểu thức đó sẽ bị bỏ qua. Có những trường hợp sử dụng toán tử này là cần thiết nhưng gửi thư không phải là một trong số đó.
Nếu mã của bạn chứa @mail(...)
thì bạn có thể đang ẩn các thông báo lỗi quan trọng sẽ giúp bạn gỡ lỗi này. Loại bỏ @
và xem nếu có bất kỳ lỗi được báo cáo.
Nó chỉ được khuyến khích khi bạn kiểm traerror_get_last()
ngay sau đó cho các lỗi cụ thể.
Kiểm tra mail()
giá trị trả lại
Các mail()
chức năng:
Trả về TRUE
nếu thư được chấp nhận thành công để gửi, FALSE
nếu không. Điều quan trọng cần lưu ý là chỉ vì thư được chấp nhận để gửi, điều đó KHÔNG có nghĩa là thư sẽ thực sự đến đích.
Điều này rất quan trọng để lưu ý bởi vì:
- Nếu bạn nhận được
FALSE
giá trị trả về, bạn biết lỗi nằm ở việc máy chủ của bạn chấp nhận thư của bạn. Đây có lẽ không phải là vấn đề mã hóa mà là vấn đề cấu hình máy chủ. Bạn cần nói chuyện với quản trị viên hệ thống của bạn để tìm hiểu lý do tại sao điều này xảy ra.
- Nếu bạn nhận được
TRUE
giá trị trả về, điều đó không có nghĩa là email của bạn chắc chắn sẽ được gửi. Nó chỉ có nghĩa là email đã được gửi đến trình xử lý tương ứng của nó trên máy chủ bởi PHP. Vẫn còn nhiều điểm thất bại ngoài tầm kiểm soát của PHP có thể khiến email không được gửi.
Vì vậy, FALSE
sẽ giúp chỉ cho bạn đi đúng hướng trong khi TRUE
không không nhất thiết có nghĩa email của bạn đã được gửi thành công. Điều này rất quan trọng cần lưu ý!
Đảm bảo nhà cung cấp dịch vụ lưu trữ của bạn cho phép bạn gửi email và không giới hạn gửi thư
Nhiều webhost được chia sẻ, đặc biệt là các nhà cung cấp webhosting miễn phí, không cho phép gửi email từ máy chủ của họ hoặc giới hạn số lượng có thể được gửi trong bất kỳ khoảng thời gian nhất định nào. Điều này là do những nỗ lực của họ để hạn chế những kẻ gửi thư rác tận dụng các dịch vụ rẻ hơn của họ.
Nếu bạn nghĩ rằng máy chủ của bạn có giới hạn gửi email hoặc chặn gửi email, hãy kiểm tra Câu hỏi thường gặp của họ để xem họ có liệt kê bất kỳ giới hạn nào như vậy không. Mặt khác, bạn có thể cần liên hệ với bộ phận hỗ trợ của họ để xác minh xem có bất kỳ hạn chế nào xảy ra xung quanh việc gửi email không.
Kiểm tra thư mục thư rác; ngăn email bị gắn cờ là thư rác
Thông thường, vì nhiều lý do, các email được gửi qua PHP (và các ngôn ngữ lập trình phía máy chủ khác) kết thúc trong thư mục thư rác của người nhận. Luôn luôn kiểm tra ở đó trước khi xử lý sự cố mã của bạn.
Để tránh thư được gửi qua PHP không được gửi đến thư mục thư rác của người nhận, có nhiều cách bạn có thể làm, cả trong mã PHP của bạn và mặt khác, để giảm thiểu khả năng email của bạn bị đánh dấu là thư rác. Những lời khuyên hay từ Michiel de Mare bao gồm:
- Sử dụng các phương thức xác thực email, chẳng hạn như SPF và DKIM để chứng minh rằng email và tên miền của bạn thuộc về nhau và để tránh giả mạo tên miền của bạn. Trang web SPF bao gồm một trình hướng dẫn để tạo thông tin DNS cho trang web của bạn.
- Kiểm tra DNS ngược của bạn để đảm bảo địa chỉ IP của máy chủ thư của bạn trỏ đến tên miền bạn sử dụng để gửi thư.
- Đảm bảo rằng địa chỉ IP bạn đang sử dụng không nằm trong danh sách đen
- Đảm bảo rằng địa chỉ trả lời là một địa chỉ hiện có, hợp lệ.
- Sử dụng tên đầy đủ, tên thật của người nhận trong trường Đến, không chỉ địa chỉ email (ví dụ
"John Smith" <john@blacksmiths-international.com>
).
- Theo dõi các tài khoản lạm dụng của bạn, chẳng hạn như lạm dụng@yourdomain.com và postmaster@yourdomain.com. Điều đó có nghĩa là - đảm bảo rằng các tài khoản này tồn tại, đọc những gì được gửi cho họ và hành động theo khiếu nại.
- Cuối cùng, làm cho nó thực sự dễ dàng để hủy đăng ký. Nếu không, người dùng của bạn sẽ hủy đăng ký bằng cách nhấn nút spam và điều đó sẽ ảnh hưởng đến danh tiếng của bạn.
Xem Làm thế nào để bạn chắc chắn rằng email bạn gửi theo chương trình không tự động được đánh dấu là thư rác? để biết thêm về chủ đề này.
Đảm bảo rằng tất cả các tiêu đề thư được cung cấp
Một số phần mềm spam sẽ từ chối thư nếu thiếu các tiêu đề phổ biến như "Từ" và "Trả lời":
$headers = array("From: from@example.com",
"Reply-To: replyto@example.com",
"X-Mailer: PHP/" . PHP_VERSION
);
$headers = implode("\r\n", $headers);
mail($to, $subject, $message, $headers);
Đảm bảo tiêu đề thư không có lỗi cú pháp
Tiêu đề không hợp lệ cũng tệ như không có tiêu đề. Một ký tự không chính xác có thể là tất cả những gì cần thiết để làm hỏng email của bạn. Kiểm tra kỹ để đảm bảo cú pháp của bạn là chính xác vì PHP sẽ không bắt những lỗi này cho bạn.
$headers = array("From from@example.com", // missing colon
"Reply To: replyto@example.com", // missing hyphen
"X-Mailer: "PHP"/" . PHP_VERSION // bad quotes
);
Đừng sử dụng From:
người gửi giả
Mặc dù thư phải có Từ: người gửi, bạn không được sử dụng bất kỳ giá trị nào . Các địa chỉ người gửi cụ thể do người dùng sử dụng là một cách chắc chắn để gửi thư bị chặn:
$headers = array("From: $_POST[contactform_sender_email]"); // No!
Lý do: web hoặc máy chủ gửi thư của bạn không phải là SPF / DKIM được liệt kê trong danh sách trắng để giả vờ chịu trách nhiệm về các địa chỉ @hotmail hoặc @gmail. Nó thậm chí có thể âm thầm thả thư với From:
tên miền người gửi mà nó không được định cấu hình.
Đảm bảo giá trị người nhận là chính xác
Đôi khi vấn đề đơn giản như có một giá trị không chính xác cho người nhận email. Điều này có thể là do sử dụng một biến không chính xác.
$to = 'user@example.com';
// other variables ....
mail($recipient, $subject, $message, $headers); // $recipient should be $to
Một cách khác để kiểm tra điều này là mã cứng giá trị người nhận vào lệnh mail()
gọi hàm:
mail('user@example.com', $subject, $message, $headers);
Điều này có thể áp dụng cho tất cả các mail()
tham số.
Gửi tới nhiều tài khoản
Để giúp loại trừ các sự cố tài khoản email, hãy gửi email của bạn đến nhiều tài khoản email tại các nhà cung cấp email khác nhau . Nếu email của bạn không đến tài khoản Gmail của người dùng, hãy gửi cùng một email đến tài khoản Yahoo, tài khoản Hotmail và tài khoản POP3 thông thường (như tài khoản email do ISP cung cấp).
Nếu các email đến tất cả hoặc một số tài khoản email khác, bạn biết mã của bạn đang gửi email nhưng có khả năng nhà cung cấp tài khoản email đang chặn chúng vì một số lý do. Nếu email không đến bất kỳ tài khoản email nào, vấn đề có nhiều khả năng liên quan đến mã của bạn.
Đảm bảo mã khớp với phương thức biểu mẫu
Nếu bạn đã đặt phương thức biểu mẫu của mình thành POST
, hãy đảm bảo rằng bạn đang sử dụng $_POST
để tìm kiếm các giá trị biểu mẫu của mình. Nếu bạn đã đặt thành GET
hoặc không đặt nó ở tất cả, hãy đảm bảo bạn sử dụng $_GET
để tìm giá trị biểu mẫu của mình.
Đảm bảo action
giá trị biểu mẫu của bạn trỏ đến đúng vị trí
Hãy chắc chắn rằng action
thuộc tính biểu mẫu của bạn chứa một giá trị trỏ đến mã gửi thư PHP của bạn.
<form action="send_email.php" method="POST">
Đảm bảo máy chủ web hỗ trợ gửi email
Một số nhà cung cấp dịch vụ lưu trữ web không cho phép hoặc cho phép gửi email thông qua máy chủ của họ. Lý do cho việc này có thể khác nhau nhưng nếu họ đã vô hiệu hóa việc gửi thư, bạn sẽ cần sử dụng một phương pháp thay thế sử dụng bên thứ ba để gửi những email đó cho bạn.
Một email đến bộ phận hỗ trợ kỹ thuật của họ (sau chuyến đi tới bộ phận hỗ trợ trực tuyến hoặc Câu hỏi thường gặp của họ) sẽ làm rõ nếu khả năng email có sẵn trên máy chủ của bạn.
Đảm bảo rằng localhost
máy chủ thư được cấu hình
Nếu bạn đang phát triển trên máy trạm cục bộ của mình bằng WAMP, MAMP hoặc XAMPP, máy chủ email có thể không được cài đặt trên máy trạm của bạn. Không có ai, PHP không thể gửi thư theo mặc định.
Bạn có thể khắc phục điều này bằng cách cài đặt một máy chủ thư cơ bản. Đối với Windows, bạn có thể sử dụng Mercury Mail miễn phí .
Bạn cũng có thể sử dụng SMTP để gửi email của mình. Xem câu trả lời tuyệt vời này từ Vikas Dwivingi để tìm hiểu làm thế nào để làm điều này.
Kích hoạt tùy chỉnh của PHP mail.log
Ngoài tệp nhật ký của MTA và PHP, bạn có thể kích hoạt tính năng ghi nhật ký cho mail()
chức năng một cách cụ thể. Nó không ghi lại tương tác SMTP hoàn chỉnh, nhưng ít nhất là chức năng tham số cuộc gọi và tập lệnh gọi.
ini_set("mail.log", "/tmp/mail.log");
ini_set("mail.add_x_header", TRUE);
Xem http://php.net/manual/en/mail.configuration.php để biết chi tiết. (Tốt nhất là để cho phép các tùy chọn này trong php.ini
hoặc .user.ini
hoặc .htaccess
có lẽ.)
Kiểm tra với một dịch vụ kiểm tra thư
Có nhiều dịch vụ kiểm tra giao hàng và kiểm tra spam mà bạn có thể sử dụng để kiểm tra thiết lập MTA / máy chủ web của mình. Thông thường, bạn gửi một thăm dò thư đến: địa chỉ của họ, sau đó nhận được báo cáo gửi và các thất bại hoặc phân tích cụ thể hơn sau:
Sử dụng một bưu phẩm khác
mail()
Hàm dựng sẵn của PHP rất tiện dụng và thường hoàn thành công việc nhưng nó có những thiếu sót . May mắn thay, có những lựa chọn thay thế cung cấp nhiều sức mạnh và tính linh hoạt hơn bao gồm xử lý rất nhiều vấn đề được nêu ở trên:
Tất cả đều có thể được kết hợp với một nhà cung cấp dịch vụ / máy chủ SMTP chuyên nghiệp. (Bởi vì 08/15 gói chia sẻ webhosting điển hình bị tấn công hoặc bỏ lỡ khi cài đặt / cấu hình email.)