แม้ว่าจะมีบางส่วนของคำตอบนี้ที่ใช้กับการใช้งานmail()
ฟังก์ชั่นของตัวเองเท่านั้น แต่ขั้นตอนการแก้ไขปัญหาเหล่านี้สามารถนำไปใช้กับระบบส่งเมล PHP ได้
มีสาเหตุหลายประการที่สคริปต์ของคุณดูเหมือนจะไม่ส่งอีเมล เป็นการยากที่จะวินิจฉัยสิ่งเหล่านี้หากไม่มีข้อผิดพลาดทางไวยากรณ์ที่ชัดเจน หากไม่มีใครที่คุณจะต้องดำเนินการผ่านรายการตรวจสอบด้านล่างเพื่อค้นหาข้อผิดพลาดที่อาจเกิดขึ้นที่คุณอาจประสบ
ตรวจสอบให้แน่ใจว่าการรายงานข้อผิดพลาดเปิดใช้งานและตั้งค่าให้รายงานข้อผิดพลาดทั้งหมด
การรายงานข้อผิดพลาดมีความสำคัญต่อการรูทบักในโค้ดและข้อผิดพลาดทั่วไปที่ PHP พบ ต้องเปิดใช้งานการรายงานข้อผิดพลาดเพื่อรับข้อผิดพลาดเหล่านี้ การวางรหัสต่อไปนี้ที่ด้านบนของไฟล์ PHP ของคุณ (หรือในไฟล์กำหนดค่าหลัก) จะเปิดใช้งานการรายงานข้อผิดพลาด
error_reporting(-1);
ini_set('display_errors', 'On');
set_error_handler("var_dump");
ดูฉันจะรับข้อความแสดงข้อผิดพลาดที่เป็นประโยชน์ใน PHP ได้อย่างไร - คำตอบนี้สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับเรื่องนี้
ตรวจสอบให้แน่ใจว่าmail()
มีการเรียกใช้ฟังก์ชัน
มันอาจดูโง่ แต่ข้อผิดพลาดทั่วไปคือลืมที่จะวางmail()
ฟังก์ชั่นในรหัสของคุณ ตรวจสอบให้แน่ใจว่ามีและไม่ได้แสดงความคิดเห็น
ตรวจสอบให้แน่ใจว่าmail()
มีการเรียกใช้ฟังก์ชันอย่างถูกต้อง
บูลเมล (สตริง $ ถึง, สตริง $ subject, สตริง $ message [, สตริง $ more_headers [, สตริง $ extra_parameters]])
ฟังก์ชั่นเมลใช้พารามิเตอร์ที่จำเป็นสามตัวและเลือกหนึ่งในสี่และห้า ถ้าคุณโทรไปmail()
ไม่มีพารามิเตอร์อย่างน้อยสามพารามิเตอร์จะล้มเหลว
ถ้าคุณโทรไป mail()
ไม่มีพารามิเตอร์ที่ถูกต้องในลำดับที่ถูกต้องมันจะล้มเหลวเช่นกัน
ตรวจสอบบันทึกเมลของเซิร์ฟเวอร์
เว็บเซิร์ฟเวอร์ของคุณควรเข้าสู่ระบบพยายามส่งอีเมลทั้งหมด สถานที่ตั้งของบันทึกเหล่านี้จะแตกต่างกัน (คุณอาจต้องขอให้ผู้ดูแลระบบเซิร์ฟเวอร์ของคุณที่พวกเขาอยู่) logs
แต่พวกเขาสามารถทั่วไปจะพบในภายใต้ไดเรกทอรีรากของผู้ใช้ ภายในจะเป็นข้อความแสดงข้อผิดพลาดที่เซิร์ฟเวอร์รายงานหากมีเกี่ยวข้องกับความพยายามในการส่งอีเมลของคุณ
ตรวจสอบความล้มเหลวในการเชื่อมต่อพอร์ต
บล็อกพอร์ตเป็นปัญหาที่พบบ่อยซึ่งนักพัฒนาซอฟต์แวร์ส่วนใหญ่เผชิญในขณะที่รวมรหัสเพื่อส่งอีเมลโดยใช้ SMTP และสิ่งนี้สามารถติดตามได้อย่างง่ายดายที่เซิร์ฟเวอร์ maillogs (ตำแหน่งของเซิร์ฟเวอร์ของบันทึกไฟล์เมลอาจแตกต่างกันไปตามเซิร์ฟเวอร์ตามที่อธิบายไว้ข้างต้น) ในกรณีที่คุณอยู่บนเซิร์ฟเวอร์โฮสต์ที่ใช้ร่วมกันพอร์ต 25 และ 587 จะยังคงถูกบล็อกโดยค่าเริ่มต้น บล็อกนี้ดำเนินการโดยผู้ให้บริการโฮสต์ของคุณ สิ่งนี้เป็นจริงแม้กับเซิร์ฟเวอร์เฉพาะบางตัว เมื่อพอร์ตเหล่านี้ถูกบล็อกให้ลองเชื่อมต่อโดยใช้พอร์ต 2525 หากคุณพบว่าพอร์ตนั้นถูกบล็อกด้วยวิธีแก้ปัญหาเดียวคือติดต่อผู้ให้บริการโฮสต์ของคุณเพื่อปลดบล็อกพอร์ตเหล่านี้
ผู้ให้บริการโฮสติ้งส่วนใหญ่บล็อกพอร์ตอีเมลเหล่านี้เพื่อป้องกันเครือข่ายจากการส่งอีเมลขยะ
ใช้พอร์ต 25 หรือ 587 สำหรับการเชื่อมต่อธรรมดา / TLS และพอร์ต 465 สำหรับการเชื่อมต่อ SSL สำหรับผู้ใช้ส่วนใหญ่ขอแนะนำให้ใช้พอร์ต 587 เพื่อหลีกเลี่ยงข้อ จำกัด อัตราที่กำหนดโดยผู้ให้บริการโฮสต์บางราย
อย่าใช้ตัวดำเนินการปราบปรามข้อผิดพลาด
เมื่อโอเปอเรเตอร์การปราบปรามข้อผิดพลาด @
ถูกนำเสนอต่อนิพจน์ใน PHP ข้อความแสดงข้อผิดพลาดใด ๆ ที่อาจสร้างขึ้นโดยนิพจน์นั้นจะถูกละเว้น มีสถานการณ์ที่จำเป็นต้องใช้ตัวดำเนินการนี้ แต่การส่งจดหมายไม่ใช่หนึ่งในนั้น
หากรหัสของคุณมีอยู่@mail(...)
คุณอาจซ่อนข้อความแสดงข้อผิดพลาดที่สำคัญซึ่งจะช่วยให้คุณแก้ไขข้อผิดพลาดนี้ ลบ@
และดูว่ามีรายงานข้อผิดพลาดใด ๆ หรือไม่
ขอแนะนำให้เฉพาะเมื่อคุณตรวจสอบerror_get_last()
ความเสียหายที่เป็นรูปธรรมในภายหลัง
ตรวจสอบmail()
ค่าส่งคืน
mail()
ฟังก์ชั่น:
ส่งคืนTRUE
ถ้าเมลได้รับการยอมรับสำหรับการจัดส่งเป็นFALSE
อย่างอื่น เป็นสิ่งสำคัญที่จะต้องทราบว่าเพียงเพราะอีเมลได้รับการยอมรับสำหรับการจัดส่งก็ไม่ได้หมายความว่าอีเมลจะไปถึงปลายทางที่ต้องการจริงๆ
สิ่งนี้เป็นสิ่งสำคัญที่ควรทราบเนื่องจาก:
- หากคุณได้รับ
FALSE
ผลตอบแทนที่คุณรู้ว่าข้อผิดพลาดอยู่กับเซิร์ฟเวอร์ของคุณรับจดหมายของคุณ นี่อาจไม่ใช่ปัญหาการเข้ารหัส แต่เป็นปัญหาการกำหนดค่าเซิร์ฟเวอร์ คุณต้องพูดคุยกับผู้ดูแลระบบของคุณเพื่อค้นหาสาเหตุที่เกิดขึ้น
- หากคุณได้รับ
TRUE
ผลตอบแทนก็ไม่ได้หมายความว่าอีเมลของคุณจะถูกส่งอย่างแน่นอน มันหมายถึงว่าอีเมลถูกส่งไปยังตัวจัดการที่เกี่ยวข้องบนเซิร์ฟเวอร์สำเร็จโดย PHP ยังมีจุดของความล้มเหลวเพิ่มเติมนอกเหนือจากการควบคุมของ PHP ที่สามารถทำให้อีเมลไม่ถูกส่ง
ดังนั้นFALSE
จะช่วยชี้ให้คุณในทิศทางที่ถูกต้องในขณะที่TRUE
ไม่ได้แปลว่าอีเมลของคุณถูกส่งไปเรียบร้อยแล้ว นี่เป็นสิ่งสำคัญที่ควรทราบ!
ตรวจสอบให้แน่ใจว่าผู้ให้บริการโฮสต์ของคุณอนุญาตให้คุณส่งอีเมลและไม่ จำกัด การส่งอีเมล
webhosts ที่ใช้ร่วมกันหลายแห่งโดยเฉพาะผู้ให้บริการพื้นที่เว็บฟรีไม่อนุญาตให้ส่งอีเมลจากเซิร์ฟเวอร์หรือ จำกัด จำนวนเงินที่สามารถส่งได้ในช่วงเวลาใดก็ตาม นี่คือความพยายามของพวกเขาเพื่อ จำกัด ผู้ส่งอีเมลขยะจากการใช้ประโยชน์จากบริการที่ถูกกว่าของพวกเขา
หากคุณคิดว่าโฮสต์ของคุณมีข้อ จำกัด ในการส่งอีเมลหรือบล็อกการส่งอีเมลให้ตรวจสอบคำถามที่พบบ่อยเพื่อดูว่าพวกเขาแสดงรายการข้อ จำกัด ดังกล่าวหรือไม่ มิฉะนั้นคุณอาจต้องติดต่อฝ่ายสนับสนุนเพื่อยืนยันว่ามีข้อ จำกัด ใด ๆ เกิดขึ้นในการส่งอีเมลหรือไม่
ตรวจสอบโฟลเดอร์สแปม ป้องกันไม่ให้อีเมลถูกตั้งค่าสถานะว่าเป็นสแปม
บ่อยครั้งที่อีเมลที่ส่งผ่าน PHP (และภาษาการเขียนโปรแกรมด้านเซิร์ฟเวอร์อื่น ๆ ) อาจเกิดขึ้นในโฟลเดอร์สแปมของผู้รับ ตรวจสอบทุกครั้งก่อนที่จะแก้ไขปัญหารหัสของคุณ
เพื่อหลีกเลี่ยงอีเมลที่ส่งจาก PHP ไม่ให้ส่งไปยังโฟลเดอร์สแปมของผู้รับมีหลายสิ่งที่คุณสามารถทำได้ทั้งในโค้ด PHP ของคุณและอื่น ๆ เพื่อลดโอกาสที่อีเมลของคุณจะถูกทำเครื่องหมายว่าเป็นสแปม เคล็ดลับดีๆจากMichiel de Mareรวมถึง:
- ใช้วิธีการตรวจสอบสิทธิ์อีเมลเช่นSPFและDKIMเพื่อพิสูจน์ว่าอีเมลและชื่อโดเมนของคุณอยู่ด้วยกันและเพื่อป้องกันการแอบอ้างชื่อโดเมนของคุณ เว็บไซต์ SPF มีตัวช่วยสร้างเพื่อสร้างข้อมูล DNS สำหรับเว็บไซต์ของคุณ
- ตรวจสอบDNS ย้อนกลับของคุณเพื่อให้แน่ใจว่าที่อยู่ IP ของเซิร์ฟเวอร์อีเมลของคุณชี้ไปที่ชื่อโดเมนที่คุณใช้สำหรับส่งจดหมาย
- ตรวจสอบให้แน่ใจว่าที่อยู่ IP ที่คุณใช้ไม่ได้อยู่ในบัญชีดำ
- ตรวจสอบให้แน่ใจว่าที่อยู่ตอบกลับเป็นที่อยู่ที่ถูกต้องและมีอยู่
- ใช้ชื่อจริงของผู้รับในช่องถึงไม่ใช่แค่ที่อยู่อีเมล (เช่น
"John Smith" <john@blacksmiths-international.com>
)
- ตรวจสอบบัญชีการละเมิดของคุณเช่น abuse@yourdomain.com และ postmaster@yourdomain.com นั่นหมายถึง - ตรวจสอบให้แน่ใจว่าบัญชีเหล่านี้มีอยู่อ่านสิ่งที่ส่งไปยังพวกเขาและดำเนินการกับการร้องเรียน
- สุดท้ายให้มันจริงๆเรื่องง่ายที่จะยกเลิกการเป็นสมาชิก มิฉะนั้นผู้ใช้ของคุณจะยกเลิกการสมัครโดยกดปุ่มสแปมและที่จะส่งผลกระทบต่อชื่อเสียงของคุณ
ดูคุณแน่ใจได้อย่างไรว่าอีเมลที่คุณส่งโดยทางโปรแกรมไม่ได้ถูกทำเครื่องหมายว่าเป็นสแปมโดยอัตโนมัติ สำหรับเพิ่มเติมในหัวข้อนี้
ตรวจสอบให้แน่ใจว่าได้จัดส่งส่วนหัวจดหมายทั้งหมด
ซอฟต์แวร์สแปมบางตัวจะปฏิเสธอีเมลหากไม่มีส่วนหัวร่วมเช่น "จาก" และ "ตอบกลับ":
$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);
ตรวจสอบว่าหัวจดหมายไม่มีข้อผิดพลาดทางไวยากรณ์
ส่วนหัวที่ไม่ถูกต้องไม่ดีเท่าที่ไม่มีส่วนหัว หนึ่งอักขระที่ไม่ถูกต้องอาจเป็นไปได้ทั้งหมดที่ทำให้อีเมลของคุณเสียหาย ตรวจสอบอีกครั้งเพื่อให้แน่ใจว่าไวยากรณ์ของคุณถูกต้องเนื่องจาก PHP จะไม่ตรวจจับข้อผิดพลาดเหล่านี้ให้คุณ
$headers = array("From from@example.com", // missing colon
"Reply To: replyto@example.com", // missing hyphen
"X-Mailer: "PHP"/" . PHP_VERSION // bad quotes
);
อย่าใช้From:
ผู้ส่งมารยาท
แม้ว่าจดหมายจะต้องมีผู้ส่งเป็น: คุณไม่สามารถใช้ค่าใด ๆ ก็ได้ โดยเฉพาะอย่างยิ่งที่อยู่ผู้ส่งผู้ใช้เป็นวิธี surefire เพื่อรับอีเมลที่ถูกบล็อก:
$headers = array("From: $_POST[contactform_sender_email]"); // No!
สาเหตุ: เว็บหรือเซิร์ฟเวอร์อีเมลของคุณไม่ใช่รายการที่อนุญาตโดย SPF / DKIM เพื่อแกล้งรับผิดชอบที่อยู่ @hotmail หรือ @gmail มันอาจวางอีเมล์ในFrom:
โดเมนผู้ส่งที่ไม่ได้กำหนดค่าไว้
ตรวจสอบให้แน่ใจว่าค่าผู้รับถูกต้อง
บางครั้งปัญหาก็ง่ายเหมือนมีค่าที่ไม่ถูกต้องสำหรับผู้รับอีเมล นี่อาจเป็นเพราะการใช้ตัวแปรที่ไม่ถูกต้อง
$to = 'user@example.com';
// other variables ....
mail($recipient, $subject, $message, $headers); // $recipient should be $to
อีกวิธีในการทดสอบนี้คือการกำหนดค่าผู้รับในการmail()
เรียกใช้ฟังก์ชัน:
mail('user@example.com', $subject, $message, $headers);
สิ่งนี้สามารถใช้กับmail()
พารามิเตอร์ทั้งหมดได้
ส่งไปหลายบัญชี
เพื่อช่วยตัดปัญหาบัญชีอีเมลให้ส่งอีเมลของคุณไปยังบัญชีอีเมลหลายบัญชีที่ผู้ให้บริการอีเมลรายอื่น หากอีเมลของคุณไม่ถึงบัญชี Gmail ของผู้ใช้ให้ส่งอีเมลเดียวกันไปยังบัญชี Yahoo บัญชี Hotmail และบัญชี POP3 ปกติ (เช่นบัญชีอีเมลที่ ISP ของคุณให้)
หากอีเมลมาถึงบัญชีอีเมลอื่นหรือบางส่วนคุณรู้ว่ารหัสของคุณกำลังส่งอีเมล แต่เป็นไปได้ว่าผู้ให้บริการบัญชีอีเมลกำลังปิดกั้นอีเมลเหล่านั้นด้วยเหตุผลบางประการ หากอีเมลไม่ถึงบัญชีอีเมลใด ๆ ปัญหาน่าจะเกี่ยวข้องกับรหัสของคุณมากกว่า
ตรวจสอบให้แน่ใจว่ารหัสตรงกับวิธีการแบบฟอร์ม
หากคุณตั้งค่าวิธีการแบบฟอร์มของคุณเป็นPOST
ตรวจสอบให้แน่ใจว่าคุณกำลังใช้$_POST
เพื่อค้นหาค่าแบบฟอร์มของคุณ หากคุณได้ตั้งค่าไว้GET
หรือไม่ได้ตั้งค่าทั้งหมดตรวจสอบให้แน่ใจว่าคุณใช้$_GET
เพื่อค้นหาค่าแบบฟอร์มของคุณ
ตรวจสอบให้แน่ใจว่าaction
ค่าของฟอร์มชี้ไปยังตำแหน่งที่ถูกต้อง
ตรวจสอบให้แน่ใจว่าaction
แอตทริบิวต์แบบฟอร์มของคุณมีค่าที่ชี้ไปยังรหัสไปรษณีย์ PHP ของคุณ
<form action="send_email.php" method="POST">
ตรวจสอบให้แน่ใจว่าโฮสต์เว็บรองรับการส่งอีเมล
ผู้ให้บริการเว็บโฮสติ้งบางรายไม่อนุญาตหรือเปิดใช้งานการส่งอีเมลผ่านเซิร์ฟเวอร์ เหตุผลนี้อาจแตกต่างกันไป แต่หากพวกเขาปิดการใช้งานการส่งจดหมายคุณจะต้องใช้วิธีการอื่นที่ใช้บุคคลที่สามเพื่อส่งอีเมลเหล่านั้นให้คุณ
อีเมลถึงฝ่ายสนับสนุนด้านเทคนิคของพวกเขา (หลังจากเดินทางไปยังฝ่ายสนับสนุนออนไลน์หรือคำถามที่พบบ่อย) ควรชี้แจงหากความสามารถของอีเมลนั้นมีอยู่ในเซิร์ฟเวอร์ของคุณ
ตรวจสอบให้แน่ใจว่าlocalhost
มีการกำหนดค่าเซิร์ฟเวอร์อีเมล
หากคุณกำลังพัฒนาบนเวิร์กสเตชันท้องถิ่นของคุณโดยใช้ WAMP, MAMP หรือ XAMPP เซิร์ฟเวอร์อีเมลอาจไม่ได้รับการติดตั้งบนเวิร์กสเตชันของคุณ หากไม่มีอย่างใดอย่างหนึ่ง PHP จะไม่สามารถส่งจดหมายได้ตามค่าเริ่มต้น
คุณสามารถเอาชนะสิ่งนี้ได้โดยการติดตั้งเมลเซิร์ฟเวอร์พื้นฐาน สำหรับ Windows คุณสามารถใช้Mercury Mailฟรี
คุณยังสามารถใช้ SMTP เพื่อส่งอีเมลของคุณ ดูคำตอบที่ยอดเยี่ยมนี้จากVikas Dwivediเพื่อเรียนรู้วิธีการทำสิ่งนี้
เปิดใช้งานกำหนดเองของ PHP mail.log
นอกเหนือจากไฟล์บันทึกของ MTA และ PHP ของคุณคุณสามารถเปิดใช้งานการบันทึกสำหรับmail()
ฟังก์ชันโดยเฉพาะ มันไม่ได้บันทึกการโต้ตอบ SMTP ที่สมบูรณ์ แต่อย่างน้อยพารามิเตอร์การเรียกใช้ฟังก์ชันและสคริปต์การเรียกใช้
ini_set("mail.log", "/tmp/mail.log");
ini_set("mail.add_x_header", TRUE);
ดูhttp://php.net/manual/th/mail.configuration.phpสำหรับรายละเอียด (ดีที่สุดที่จะช่วยให้ตัวเลือกเหล่านี้ในphp.ini
หรือ.user.ini
หรือ.htaccess
บางที.)
ตรวจสอบกับบริการทดสอบจดหมาย
มีบริการตรวจสอบการส่งและสแปมที่หลากหลายที่คุณสามารถใช้เพื่อทดสอบการตั้งค่า MTA / เว็บเซิร์ฟเวอร์ของคุณ โดยทั่วไปคุณจะส่งเครื่องมือตรวจสอบจดหมายถึง: ที่อยู่ของพวกเขาจากนั้นรับรายงานการจัดส่งและความล้มเหลวหรือการวิเคราะห์ที่เป็นรูปธรรมมากขึ้นในภายหลัง:
ใช้จดหมายที่แตกต่าง
PHP สร้างขึ้นในmail()
ฟังก์ชั่นเป็นประโยชน์และมักจะได้รับงานทำ แต่ก็มีข้อบกพร่องของตน โชคดีที่มีทางเลือกที่ให้พลังงานและความยืดหยุ่นที่มากขึ้นรวมถึงการจัดการปัญหาต่าง ๆ ที่กล่าวถึงข้างต้น
ทั้งหมดนี้สามารถใช้ร่วมกับเซิร์ฟเวอร์ SMTP / ผู้ให้บริการมืออาชีพ (เนื่องจากเว็บโฮสต์ที่ใช้ร่วมกันโดยทั่วไปของแผน 08/15 นั้นได้รับผลกระทบหรือพลาดเมื่อมีการตั้งค่า / กำหนดค่าอีเมล)