Chức năng thư trong PHP không hoàn tất việc gửi e-mail
<?php
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = '[email protected]';
$subject = 'Customer Inquiry';
$body = "From: $name\n E-Mail: $email\n Message:\n $message";
if ($_POST['submit']) {
if (mail ($to, $subject, $body, $from)) {
echo '<p>Your message has been sent!</p>';
} else {
echo '<p>Something went wrong, go back and try again!</p>';
}
}
?>
Tôi đã thử tạo một mẫu thư đơn giản. Bản thân biểu mẫu nằm trên index.html
trang của tôi , nhưng nó được gửi đến một trang riêng biệt "cảm ơn bạn đã gửi" thankyou.php
, nơi mã PHP ở trên được nhúng. Mã gửi hoàn hảo, nhưng không bao giờ gửi email. Làm thế nào tôi có thể sửa lỗi này?
Trả lời
Mặc dù có một số phần của câu trả lời này chỉ áp dụng cho việc sử dụng mail()
chính hàm, 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 được email. Rất khó để chẩn đoán những điều này trừ khi có một lỗi cú pháp rõ ràng. Nếu không có cái nào, bạn cần 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 nào mà bạn có thể gặp phải.
Đảm bảo rằng báo cáo lỗi được bật và đặt 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 được bật để nhận các lỗi này. Đặt mã sau ở đầ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 cách nào để 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.
Đảm bảo 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ị bình luận.
Đảm bảo rằng mail()
hàm được gọi chính xác
thư bool (chuỗi $ to, chuỗi $ chủ đề, chuỗi $ message [, chuỗi $ bổ sung_headers [, chuỗi $ bổ sung_parameters]])
Hàm mail nhận ba tham số bắt buộc và tùy chọn tham số thứ tư và thứ năm. Nếu lệnh gọi của bạn mail()
không có ít nhất ba tham số, nó sẽ không thành công.
Nếu cuộc gọi của bạn đến mail()
không có các tham số chính xác theo đúng thứ tự, 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 phải ghi lại tất cả các nỗ lực gửi email 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 xem chúng được đặt ở đâu) 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 logs
. Bên trong sẽ là các thông báo lỗi mà máy chủ báo cáo, nếu có, liên quan đến việc bạn cố gắng gửi email.
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 gặp phải khi tích hợp mã của họ để gửi email bằng SMTP. Và, điều này có thể dễ dàng theo dõi tại maillog của máy chủ (vị trí của máy chủ của nhật ký thư có thể khác nhau giữa các máy chủ, như đã giải thích ở trên). Trong trường hợp bạn đang sử dụng 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 thực hiện một cách có chủ đích 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ọ không gửi bất kỳ email rác nào.
Sử dụng cổng 25 hoặc 587 cho kết nối TLS / đơn giản 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ỷ lệ do một số nhà cung cấp dịch vụ lưu trữ đặt ra.
Không sử dụng toán tử ngăn chặn lỗi
Khi toán tử triệt lỗi @
được thêm vào trước 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 cần sử dụng toán tử này 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 nào được báo cáo.
Nó chỉ được khuyến khích khi bạn kiểm traerror_get_last()
ngay sau đó để tìm các hư hỏng bê tông.
Kiểm tra mail()
giá trị trả về
Các mail()
chức năng:
Trả lại
TRUE
nếu thư đã được chấp nhận gửi thành công,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 được đích đã định.
Điều quan trọng cần lưu ý 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ó thể 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 mình để tìm hiểu lý do tại sao điều này lại xảy ra. - Nếu bạn nhận được
TRUE
giá trị trả lại không có nghĩa là email của bạn chắc chắn sẽ được gửi đi. Nó chỉ có nghĩa là email đã được PHP gửi đến trình xử lý tương ứng trên máy chủ thành công. Vẫn còn nhiều điểm lỗi ngoài tầm kiểm soát của PHP có thể khiến email không được gửi đ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. Đây là điều quan trọng cần lưu ý!
Đảm bảo rằng 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 việc gửi thư
Nhiều webhosts đượ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 họ đã nỗ lực hạn chế những kẻ gửi thư rác lợi dụng các dịch vụ rẻ hơn của họ.
Nếu bạn cho rằng máy chủ của mình có giới hạn gửi email hoặc chặn việc 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. Nếu không, 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 xung quanh việc gửi email hay 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 khác nhau, 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 spam của người nhận. Luôn kiểm tra ở đó trước khi khắc phục sự cố mã của bạn.
Để tránh thư được gửi qua PHP bị gửi đến thư mục thư rác của người nhận, bạn có thể làm nhiều điều khác nhau, cả trong mã PHP của mình và nếu không, để giảm thiểu khả năng email của bạn bị đánh dấu là thư rác. Mẹo hay từ Michiel de Mare bao gồm:
- Sử dụng các phương pháp 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à để ngăn chặn việc 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 rằng địa chỉ IP của máy chủ thư của bạn trỏ đến tên miền mà 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ỉ hợp lệ, hiện có.
- Sử dụng tên thật, đầy đủ của người nhận trong trường Tới, không chỉ địa chỉ email (ví dụ
"John Smith" <[email protected]>
).- Giám sát các tài khoản lạm dụng của bạn, chẳng hạn như lạm dụ[email protected] và [email protected]. Điều đó có nghĩa là - hãy đảm bảo rằng những tài khoản này tồn tại, đọc những gì được gửi đến chúng và hành động khi 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 cách nào để đảm bảo email bạn gửi theo chương trình không tự động bị đánh dấu là spam? để biết thêm về chủ đề này.
Đảm bảo 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 nó thiếu các tiêu đề phổ biến như "Từ" và "Trả lời":
$headers = array("From: [email protected]",
"Reply-To: [email protected]",
"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àm hỏng email của bạn. Kiểm tra kỹ để đảm bảo rằng cú pháp của bạn chính xác vì PHP sẽ không mắc những lỗi này cho bạn.
$headers = array("From [email protected]", // missing colon
"Reply To: [email protected]", // missing hyphen
"X-Mailer: "PHP"/" . PHP_VERSION // bad quotes
);
Khô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 chỉ sử dụng bất kỳ giá trị nào . Đặc biệt, địa chỉ người gửi do người dùng cung cấp là một cách chắc chắn để chặn thư:
$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 nằm trong danh sách trắng SPF / DKIM để giả vờ chịu trách nhiệm về địa chỉ @hotmail hoặc @gmail. Nó thậm chí có thể âm thầm thả thư có 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 đề chỉ đơn giản là có một giá trị không chính xác cho người nhận email. Điều này có thể do sử dụng một biến không chính xác.
$to = '[email protected]';
// 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ã hóa giá trị người nhận vào lệnh mail()
gọi hàm:
mail('[email protected]', $subject, $message, $headers);
Điều này có thể áp dụng cho tất cả các mail()
tham số.
Gửi đến nhiều tài khoản
Để giúp loại trừ các vấn đề về 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 những email tương tự đế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 email đến tất cả hoặc một số tài khoản email khác, bạn biết mã của mình đ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ì lý do nào đó. Nếu email không đến bất kỳ tài khoản email nào, nhiều khả năng vấn đề 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 hoàn toàn không đặt, hãy đảm bảo rằng bạn sử dụng $_GET
để tìm kiếm các 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í
Đảm bảo 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 qua máy chủ của họ. Lý do cho điều này có thể khác nhau nhưng nếu họ đã tắt tính năng 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 gửi đến bộ phận hỗ trợ kỹ thuật của họ (sau chuyến đi đến 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õ xem khả năng email có sẵn trên máy chủ của bạn hay không.
Đảm bảo localhost
máy chủ thư được định 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ể chưa được cài đặt trên máy trạm của bạn. Nếu không có một, 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. Hãy xem câu trả lời tuyệt vời này từ Vikas Dwivedi để biết cách thực hiện điều này.
Bậ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ể bật tính năng ghi nhật kýmail()
cụ thể cho hàm . Nó không ghi lại toàn bộ tương tác SMTP, nhưng ít nhất là các tham số gọi hàm 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à bật các tùy chọn này trong php.ini
hoặc .user.ini
hoặc .htaccess
có thể.)
Kiểm tra bằng dịch vụ kiểm tra thư
Có nhiều dịch vụ phân phối và kiểm tra độ nhạy khác nhau 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ư tới: địa chỉ của họ, sau đó nhận được báo cáo gửi và các lỗi hoặc phân tích cụ thể hơn sau:
- mail-tester.com (miễn phí / đơn giản)
- glockapps.com (miễn phí / $$$)
- senforensics.com (đăng ký / $$$)
- mailtrap.io (pro / $$$)
- ultratools /… / emailTest (miễn phí / chỉ kiểm tra MX)
- Nhiều: http://www.verticalresponse.com/blog/7-email-testing-delivery-tools/
Sử dụng một phong bì khác
mail()
Hàm tích hợp 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 khuyết điểm . 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:
- Phổ biến nhất là: PHPMailer
- Tính năng tương tự: SwiftMailer
- Hoặc thậm chí PEAR :: Mail cũ hơn .
Tất cả đều có thể được kết hợp với một máy chủ / nhà cung cấp dịch vụ SMTP chuyên nghiệp. (Bởi vì 08/15 kế hoạch lưu trữ web được chia sẻ thông thường bị ảnh hưởng hoặc bị bỏ lỡ khi nói đến khả năng thiết lập / cấu hình email.)
Thêm tiêu đề thư trong chức năng thư:
$header = "From: [email protected]\r\n";
$header.= "MIME-Version: 1.0\r\n";
$header.= "Content-Type: text/html; charset=ISO-8859-1\r\n";
$header.= "X-Priority: 1\r\n";
$status = mail($to, $subject, $message, $header);
if($status)
{
echo '<p>Your mail has been sent!</p>';
} else {
echo '<p>Something went wrong. Please try again!</p>';
}
- Luôn thử gửi tiêu đề trong chức năng thư.
- Nếu bạn đang gửi thư qua localhost thì hãy thực hiện cài đặt SMTP để gửi thư.
- Nếu bạn đang gửi thư qua máy chủ thì hãy kiểm tra xem tính năng gửi email đã được bật trên máy chủ của bạn chưa.
Nếu bạn đang sử dụng cấu hình SMTP để gửi email của mình, hãy thử sử dụng PHPMailer . Bạn có thể tải xuống thư viện từ https://github.com/PHPMailer/PHPMailer .
Tôi đã tạo email của mình để gửi theo cách này:
function send_mail($email, $recipient_name, $message='')
{
require("phpmailer/class.phpmailer.php");
$mail = new PHPMailer();
$mail->CharSet = "utf-8";
$mail->IsSMTP(); // Set mailer to use SMTP
$mail->Host = "mail.example.com"; // Specify main and backup server
$mail->SMTPAuth = true; // Turn on SMTP authentication
$mail->Username = "myusername"; // SMTP username
$mail->Password = "p@ssw0rd"; // SMTP password
$mail->From = "[email protected]";
$mail->FromName = "System-Ad";
$mail->AddAddress($email, $recipient_name);
$mail->WordWrap = 50; // Set word wrap to 50 characters
$mail->IsHTML(true); // Set email format to HTML (true) or plain text (false)
$mail->Subject = "This is a Sampleenter code here Email";
$mail->Body = $message;
$mail->AltBody = "This is the body in plain text for non-HTML mail clients";
$mail->AddEmbeddedImage('images/logo.png', 'logo', 'logo.png');
$mail->addAttachment('files/file.xlsx');
if(!$mail->Send())
{
echo "Message could not be sent. <p>";
echo "Mailer Error: " . $mail->ErrorInfo;
exit;
}
echo "Message has been sent";
}
Chỉ cần thêm một số tiêu đề trước khi gửi thư:
<?php
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = '[email protected]';
$subject = 'Customer Inquiry';
$body = "From: $name\n E-Mail: $email\n Message:\n $message";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html\r\n";
$headers .= 'From: [email protected]' . "\r\n" .
'Reply-To: [email protected]' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
Và một điều nữa. Các mail()
chức năng không hoạt động trong localhost. Tải mã của bạn lên máy chủ và thử.
Nó đã làm việc cho tôi trên 000webhost bằng cách làm như sau:
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type: text/html; charset=iso-8859-1" . "\r\n";
$headers .= "From: ". $from. "\r\n";
$headers .= "Reply-To: ". $from. "\r\n";
$headers .= "X-Mailer: PHP/" . phpversion();
$headers .= "X-Priority: 1" . "\r\n";
Nhập trực tiếp địa chỉ email khi gửi email:
mail('[email protected]', $subject, $message, $headers)
Sử dụng ''
và không ""
.
Mã này hoạt động, nhưng email được nhận với độ trễ nửa giờ.
Hầu hết mail()
chức năng bị vô hiệu hóa trong chia sẻ lưu trữ. Một lựa chọn tốt hơn là sử dụng SMTP. Lựa chọn tốt nhất sẽ là Gmail hoặc SendGrid.
SMTPconfig.php
<?php
$SmtpServer="smtp.*.*";
$SmtpPort="2525"; //default
$SmtpUser="***";
$SmtpPass="***";
?>
SMTPmail.php
<?php
class SMTPClient
{
function SMTPClient ($SmtpServer, $SmtpPort, $SmtpUser, $SmtpPass, $from, $to, $subject, $body)
{
$this->SmtpServer = $SmtpServer;
$this->SmtpUser = base64_encode ($SmtpUser);
$this->SmtpPass = base64_encode ($SmtpPass);
$this->from = $from;
$this->to = $to;
$this->subject = $subject;
$this->body = $body;
if ($SmtpPort == "")
{
$this->PortSMTP = 25;
}
else
{
$this->PortSMTP = $SmtpPort;
}
}
function SendMail ()
{
$newLine = "\r\n";
$headers = "MIME-Version: 1.0" . $newLine;
$headers .= "Content-type: text/html; charset=iso-8859-1" . $newLine;
if ($SMTPIN = fsockopen ($this->SmtpServer, $this->PortSMTP))
{
fputs ($SMTPIN, "EHLO ".$HTTP_HOST."\r\n");
$talk["hello"] = fgets ( $SMTPIN, 1024 );
fputs($SMTPIN, "auth login\r\n");
$talk["res"]=fgets($SMTPIN,1024);
fputs($SMTPIN, $this->SmtpUser."\r\n");
$talk["user"]=fgets($SMTPIN,1024);
fputs($SMTPIN, $this->SmtpPass."\r\n");
$talk["pass"]=fgets($SMTPIN,256);
fputs ($SMTPIN, "MAIL FROM: <".$this->from.">\r\n");
$talk["From"] = fgets ( $SMTPIN, 1024 );
fputs ($SMTPIN, "RCPT TO: <".$this->to.">\r\n");
$talk["To"] = fgets ($SMTPIN, 1024);
fputs($SMTPIN, "DATA\r\n");
$talk["data"]=fgets( $SMTPIN,1024 );
fputs($SMTPIN, "To: <".$this->to.">\r\nFrom: <".$this->from.">\r\n".$headers."\n\nSubject:".$this->subject."\r\n\r\n\r\n".$this->body."\r\n.\r\n");
$talk["send"]=fgets($SMTPIN,256);
//CLOSE CONNECTION AND EXIT ...
fputs ($SMTPIN, "QUIT\r\n");
fclose($SMTPIN);
//
}
return $talk;
}
}
?>
contact_email.php
<?php
include('SMTPconfig.php');
include('SMTPmail.php');
if($_SERVER["REQUEST_METHOD"] == "POST")
{
$to = "";
$from = $_POST['email'];
$subject = "Enquiry";
$body = $_POST['name'].'</br>'.$_POST['companyName'].'</br>'.$_POST['tel'].'</br>'.'<hr />'.$_POST['message'];
$SMTPMail = new SMTPClient ($SmtpServer, $SmtpPort, $SmtpUser, $SmtpPass, $from, $to, $subject, $body);
$SMTPChat = $SMTPMail->SendMail();
}
?>
Nếu bạn chỉ sử dụng mail()
chức năng, bạn cần hoàn thành tệp cấu hình.
Bạn cần mở phần mở rộng thư và đặt SMTP smtp_port
vân vân và quan trọng nhất là tên người dùng và mật khẩu của bạn. Nếu không có điều đó, thư không thể được gửi. Ngoài ra, bạn có thể sử dụng PHPMail
lớp để gửi.
Hãy thử hai điều này riêng biệt và cùng nhau:
- gỡ bỏ
if($_POST['submit']){}
- loại bỏ
$from
(chỉ ruột của tôi)
Tôi nghĩ rằng điều này nên làm thủ thuật. Tôi vừa thêm một if(isset
và thêm nối vào các biến trong phần thân để tách PHP khỏi HTML.
<?php
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = '[email protected]';
$subject = 'Customer Inquiry';
$body = "From:" .$name."\r\n E-Mail:" .$email."\r\n Message:\r\n" .$message;
if (isset($_POST['submit']))
{
if (mail ($to, $subject, $body, $from))
{
echo '<p>Your message has been sent!</p>';
}
else
{
echo '<p>Something went wrong, go back and try again!</p>';
}
}
?>
Đối với bất kỳ ai nhận thấy điều này đang diễn ra, tôi sẽ không khuyên bạn nên sử dụng mail
. Có một số câu trả lời liên quan đến điều này, nhưng không phải lý do tại sao của nó.
mail
Chức năng của PHP không chỉ không rõ ràng, nó hoàn toàn dựa vào bất kỳ MTA nào bạn sử dụng (tức là Sendmail ) để thực hiện công việc. mail
sẽ chỉ cho bạn biết nếu MTA không chấp nhận nó (tức là Sendmail đã bị lỗi khi bạn cố gắng gửi). Nó không thể cho bạn biết liệu thư có thành công hay không vì nó đã được gửi đi. Như vậy (chẳng hạn như chi tiết câu trả lời của John Conde ), bây giờ bạn có thể tìm hiểu nhật ký của MTA và hy vọng rằng nó sẽ cho bạn biết đủ về lỗi không thể khắc phục được. Nếu bạn đang ở trên một máy chủ được chia sẻ hoặc không có quyền truy cập vào nhật ký MTA, bạn đã gặp may. Đáng buồn thay, mặc định cho hầu hết các bản cài đặt vani cho Linux xử lý nó theo cách này.
Thư viện thư ( PHPMailer , Zend Framework 2+, v.v.), làm một cái gì đó rất khác với mail
. Họ mở một ổ cắm trực tiếp đến máy chủ thư nhận và sau đó gửi các lệnh thư SMTP trực tiếp qua ổ cắm đó. Nói cách khác, lớp hoạt động như MTA của riêng nó (lưu ý rằng bạn có thể yêu cầu các thư viện sử dụng mail
để cuối cùng gửi thư, nhưng tôi thực sự khuyên bạn không nên làm điều đó).
Điều này có nghĩa là bạn sau đó có thể trực tiếp xem các phản hồi từ máy chủ nhận (ví dụ: trong PHPMailer, bạn có thể bật đầu ra gỡ lỗi ). Không còn phải đoán xem thư không gửi được hay tại sao.
Nếu bạn đang sử dụng SMTP (tức là bạn đang gọi
isSMTP()
), bạn có thể nhận được bản ghi chi tiết của cuộc hội thoại SMTP bằng cách sử dụng thuộcSMTPDebug
tính.Đặt tùy chọn này bằng cách bao gồm một dòng như thế này trong tập lệnh của bạn:
$mail->SMTPDebug = 2;
Bạn cũng nhận được lợi ích của một giao diện tốt hơn. Với việc mail
bạn phải thiết lập tất cả các tiêu đề, tệp đính kèm, v.v. Với thư viện, bạn có một chức năng chuyên dụng để làm điều đó. Nó cũng có nghĩa là hàm đang thực hiện tất cả các phần phức tạp (như tiêu đề).
$name = $_POST['name'];
$email = $_POST['email'];
$reciver = '/* Reciver Email address */';
if (filter_var($reciver, FILTER_VALIDATE_EMAIL)) {
$subject = $name;
// To send HTML mail, the Content-type header must be set.
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .= 'From:' . $email. "\r\n"; // Sender's Email
//$headers .= 'Cc:' . $email. "\r\n"; // Carbon copy to Sender
$template = '<div style="padding:50px; color:white;">Hello ,<br/>'
. '<br/><br/>'
. 'Name:' .$name.'<br/>'
. 'Email:' .$email.'<br/>'
. '<br/>'
. '</div>';
$sendmessage = "<div style=\"background-color:#7E7E7E; color:white;\">" . $template . "</div>";
// Message lines should not exceed 70 characters (PHP rule), so wrap it.
$sendmessage = wordwrap($sendmessage, 70);
// Send mail by PHP Mail Function.
mail($reciver, $subject, $sendmessage, $headers);
echo "Your Query has been received, We will contact you soon.";
} else {
echo "<span>* invalid email *</span>";
}
Bạn có thể sử dụng email cấu hình bằng CodeIgniter . Ví dụ: sử dụng SMTP (cách đơn giản):
$config = Array(
'protocol' => 'smtp',
'smtp_host' => 'mail.domain.com', // Your SMTP host
'smtp_port' => 26, // Default port for SMTP
'smtp_user' => '[email protected]',
'smtp_pass' => 'password',
'mailtype' => 'html',
'charset' => 'iso-8859-1',
'wordwrap' => TRUE
);
$message = 'Your msg';
$this->load->library('email', $config);
$this->email->from('[email protected]', 'Title');
$this->email->to('[email protected]');
$this->email->subject('Header');
$this->email->message($message);
if($this->email->send())
{
// Conditional true
}
Nó hoạt động cho tôi!
Thử đi
if ($_POST['submit']) {
$success= mail($to, $subject, $body, $from);
if($success)
{
echo '
<p>Your message has been sent!</p>
';
} else {
echo '
<p>Something went wrong, go back and try again!</p>
';
}
}
Có thể vấn đề là cấu hình của máy chủ thư. Để tránh loại vấn đề này hoặc bạn không phải lo lắng về vấn đề máy chủ thư, tôi khuyên bạn nên sử dụng PHPMailer .
Nó là một plugin có mọi thứ cần thiết để gửi thư và điều duy nhất bạn phải tính đến là kích hoạt cổng SMTP (Cổng: 25 và 465).
require_once 'PHPMailer/PHPMailer.php';
require_once '/servicios/PHPMailer/SMTP.php';
require_once '/servicios/PHPMailer/Exception.php';
$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
try {
//Server settings
$mail->SMTPDebug = 0;
$mail->isSMTP();
$mail->Host = 'smtp.gmail.com';
$mail->SMTPAuth = true;
$mail->Username = '[email protected]';
$mail->Password = 'contrasenia';
$mail->SMTPSecure = 'ssl';
$mail->Port = 465;
// Recipients
$mail->setFrom('[email protected]', 'my name');
$mail->addAddress('[email protected]');
// Attachments
$mail->addAttachment('optional file'); // Add files, is optional
// Content
$mail->isHTML(true);// Set email format to HTML
$mail->Subject = utf8_decode("subject");
$mail->Body = utf8_decode("mail content");
$mail->AltBody = '';
$mail->send();
}
catch (Exception $e) {
$error = $mail->ErrorInfo;
}
Đảm bảo rằng bạn đã cài đặt Sendmail trong máy chủ của mình.
Nếu bạn đã kiểm tra mã của mình và xác minh rằng không có gì sai ở đó, hãy truy cập / var / mail và kiểm tra xem thư mục đó có trống không.
Nếu nó trống, bạn sẽ cần thực hiện:
sudo apt-get install sendmail
nếu bạn đang sử dụng máy chủ Ubuntu.
Trước hết, bạn có thể có quá nhiều tham số cho hàm mail () ... Bạn có thể có tối đa năm, mail(to, subject, message, headers, parameters);
Về phần $from
biến, biến đó sẽ tự động đến từ máy chủ web của bạn nếu bạn sử dụng cPanel của Linux . Nó tự động đến từ tên người dùng cPanel và địa chỉ IP của bạn.
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = '[email protected]';
$subject = 'Customer Inquiry';
$body = "From: $name\n E-Mail: $email\n Message:\n $message";
Đồng thời đảm bảo rằng bạn có thứ tự chính xác của các biến trong hàm mail () của mình.
Theo mail($to, $subject, $message, etc.)
thứ tự đó, nếu không sẽ có khả năng nó không hoạt động.
Nếu bạn gặp sự cố khi gửi thư bằng PHP, hãy xem xét một giải pháp thay thế như PHPMailer hoặc SwiftMailer .
Tôi thường sử dụng SwiftMailer bất cứ khi nào tôi cần gửi thư bằng PHP.
Cách sử dụng cơ bản:
require 'mail/swift_required.php';
$message = Swift_Message::newInstance()
// The subject of your email
->setSubject('Jane Doe sends you a message')
// The from address(es)
->setFrom(array('[email protected]' => 'Jane Doe'))
// The to address(es)
->setTo(array('[email protected]' => 'Frank Stevens'))
// Here, you put the content of your email
->setBody('<h3>New message</h3><p>Here goes the rest of my message</p>', 'text/html');
if (Swift_Mailer::newInstance(Swift_MailTransport::newInstance())->send($message)) {
echo json_encode([
"status" => "OK",
"message" => 'Your message has been sent!'
], JSON_PRETTY_PRINT);
} else {
echo json_encode([
"status" => "error",
"message" => 'Oops! Something went wrong!'
], JSON_PRETTY_PRINT);
}
Xem tài liệu chính thức để biết thêm thông tin về cách sử dụng SwiftMailer.
Dành cho những người không muốn sử dụng thư bên ngoài và muốn gửi thư () trên máy chủ Linux chuyên dụng.
Cách thức, cách PHP gửi thư, được mô tả php.ini
trong phần [mail function]
.
Tham số sendmail-path
mô tả cách gọi sendmail. Giá trị mặc định là sendmail -t -i
, vì vậy nếu bạn làm việc sendmail -t -i < message.txt
trong bảng điều khiển Linux - bạn sẽ hoàn tất. Bạn cũng có thể thêm mail.log
vào để gỡ lỗi và đảm bảo rằng mail () thực sự được gọi.
Các MTA khác nhau có thể triển khai sendmail
. Họ chỉ tạo một liên kết tượng trưng đến các tệp nhị phân của họ trên tên đó. Ví dụ, trong Debian , mặc định là Postfix . Định cấu hình MTA của bạn để gửi thư và kiểm tra nó từ bảng điều khiển với sendmail -v -t -i < message.txt
. Tệp message.txt
phải chứa tất cả các tiêu đề của thư và nội dung, địa chỉ đích cho phong bì sẽ được lấy từ To:
tiêu đề. Thí dụ:
From: [email protected]
To: [email protected]
Subject: Test mail via sendmail.
Text body.
Tôi thích sử dụng ssmtp làm MTA vì nó đơn giản và không yêu cầu chạy daemon với các cổng đã mở. ssmtp chỉ phù hợp để gửi thư từ localhost . Nó cũng có thể gửi email đã xác thực qua tài khoản của bạn trên dịch vụ thư công cộng. Cài đặt ssmtp và chỉnh sửa tệp cấu hình /etc/ssmtp/ssmtp.conf
. Để có thể nhận thư hệ thống cục bộ đến tài khoản Unix (ví dụ: cảnh báo tới root từ cron job), hãy cấu hình /etc/ssmtp/revaliases
tệp.
Đây là cấu hình của tôi cho tài khoản của tôi trên Yandex mail:
[email protected]
mailhub=smtp.yandex.ru:465
FromLineOverride=YES
UseTLS=YES
[email protected]
AuthPass=password
Điều này sẽ chỉ ảnh hưởng đến một số ít người dùng, nhưng tôi muốn nó được ghi lại cho một số ít đó. Thành viên của số ít đó đã dành 6 giờ để khắc phục sự cố một tập lệnh thư PHP đang hoạt động vì vấn đề này.
Nếu bạn đang đến một trường đại học chạy XAMPP từ www.AceITLab.com, bạn nên biết điều mà giáo sư của chúng tôi đã không nói với chúng tôi: Tường lửa AceITLab (không phải tường lửa Windows) chặn MercuryMail trong XAMPP. Bạn sẽ phải sử dụng một ứng dụng thư thay thế, lê đang làm việc cho chúng tôi. Bạn sẽ phải gửi đến tài khoản Gmail có cài đặt bảo mật thấp.
Vâng, tôi biết, điều này hoàn toàn vô dụng đối với email trong thế giới thực. Tuy nhiên, từ những gì tôi đã thấy, bối cảnh học thuật và thế giới thực thường có rất ít điểm chung quý giá.
Nếu bạn đang chạy mã này trên một máy chủ cục bộ (tức là máy tính của bạn cho mục đích phát triển), nó sẽ không gửi email đến người nhận. Nó sẽ tạo một .txt
tệp trong một thư mục có tên mailoutput
.
Trong trường hợp nếu bạn đang sử dụng dịch vụ hosing miễn phí, chẳng hạn như 000webhost
hoặc hostinger
, những nhà cung cấp dịch vụ đó vô hiệu hóa mail()
chức năng ngăn chặn việc sử dụng ngoài ý muốn giả mạo email, gửi thư rác, v.v. Tôi muốn bạn liên hệ với họ để xem họ có hỗ trợ tính năng này hay không.
Nếu bạn chắc chắn rằng nhà cung cấp dịch vụ hỗ trợ hàm mail (), bạn có thể kiểm tra hướng dẫn sử dụng PHP này để tham khảo thêm,
Để kiểm tra thời tiết mà dịch vụ lưu trữ của bạn có hỗ trợ chức năng mail () không, hãy thử chạy mã này (nhớ thay đổi địa chỉ email của người nhận) :
<?php
$to = '[email protected]';
$subject = 'the subject';
$message = 'hello';
$headers = 'From: [email protected]' . "\r\n" .
'Reply-To: [email protected]' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
?>
Việc cài đặt Sendmail cho Debian 10.0.0 ('Buster') trên thực tế là không đáng kể!
php.ini
[mail function]
sendmail_path=/usr/sbin/sendmail -t -i
; (Other directives are mostly windows)
Cài đặt gói sendmail tiêu chuẩn (cho phép 'gửi'):
su - # Install as user 'root'
dpkg --list # Is install necessary?
apt-get install sendmail sendmail-cf m4 # Note multiple package selection
sendmailconfig # Respond all 'Y' for new install
Các lệnh hữu ích khác:
which sendmail # /usr/sbin/sendmail
which sendmailconfig # /usr/sbin/sendmailconfig
man sendmail # Documentation
systemctl restart sendmail # As and when required
Xác minh (khả năng gửi)
echo "Subject: sendmail test" | sendmail -v <yourEmail>@gmail.com
Ở trên mất khoảng 5 phút. Sau đó, tôi đã lãng phí 5 giờ ... Đừng quên kiểm tra thư mục thư rác của bạn !
Có một số khả năng:
Bạn đang gặp sự cố máy chủ. Máy chủ không có bất kỳ máy chủ thư nào. Vì vậy, thư của bạn không hoạt động, bởi vì mã của bạn ổn và thư đang hoạt động với loại.
Bạn không nhận được giá trị đã đăng. Hãy thử mã của bạn với một giá trị tĩnh.
Sử dụng thư SMTP để gửi thư ...
Bạn có thể thấy lỗi của mình bằng cách:
error_reporting(E_ALL);
Và mã mẫu của tôi là:
<?php
use PHPMailer\PHPMailer\PHPMailer;
require 'PHPMailer.php';
require 'SMTP.php';
require 'Exception.php';
$name = $_POST['name'];
$mailid = $_POST['mail'];
$mail = new PHPMailer;
$mail->IsSMTP();
$mail->SMTPDebug = 0; // Set mailer to use SMTP
$mail->Host = 'smtp.gmail.com'; // Specify main and backup server
$mail->Port = 587; // Set the SMTP port
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = '[email protected]'; // SMTP username
$mail->Password = 'password'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable encryption, 'ssl' also accepted
$mail->From = '[email protected]';
$mail->FromName = 'name';
$mail->AddAddress($mailid, $name); // Name is optional
$mail->IsHTML(true); // Set email format to HTML
$mail->Subject = 'Here is the subject';
$mail->Body = 'Here is your message' ;
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
if (!$mail->Send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
exit;
}
echo 'Message has been sent';
?>
Nếu bạn gặp khó khăn với một ứng dụng được lưu trữ trên Hostgator, thì đây là cách giải quyết vấn đề của tôi. Cảm ơn rất nhiều đến anh chàng đã đăng giải pháp chi tiết. Trong trường hợp liên kết ngoại tuyến vào một ngày nào đó, bạn có bản tóm tắt:
- Tìm đường dẫn sendmail trong máy chủ của bạn. Một cách đơn giản để kiểm tra xem nó, là để tạm viết đoạn mã sau vào một trang duy nhất mà bạn sẽ truy cập, đọc các thông tin được tạo ra:
<?php phpinfo(); ?>
. Mở trang này và tìm kiếmsendmail path
. (Sau đó, đừng quên xóa mã này!) - Sự cố và cách khắc phục: nếu đường dẫn sendmail của bạn chỉ cho biết
-t -i
, hãy chỉnh sửa máy chủ của bạnphp.ini
và thêm dòng sau:sendmail_path = /usr/sbin/sendmail -t -i;
Nhưng, sau khi có thể gửi thư bằng mail()
chức năng PHP , tôi biết được rằng nó gửi email không được xác thực, điều gì đã tạo ra một vấn đề khác. Tất cả các email đều nằm trong hộp thư rác trên Hotmail của tôi và một số email chưa bao giờ được gửi đi, điều này tôi đoán có liên quan đến việc chúng không được xác thực. Đó là lý do tại sao tôi quyết định chuyển từ mail()
sử dụng PHPMailer
SMTP.