ฟังก์ชั่นจดหมาย PHP ไม่สามารถส่งอีเมล์ได้อย่างสมบูรณ์


477
<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];
    $from = 'From: yoursite.com';
    $to = 'contact@yoursite.com';
    $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>';
        }
    }
?>

ฉันลองสร้างแบบฟอร์มจดหมายง่ายๆ ฟอร์มนั้นอยู่ในindex.htmlหน้าของฉันแต่มันส่งไปยังหน้า "ขอบคุณสำหรับการส่งของคุณ" แยกต่างหากthankyou.phpโดยที่โค้ด PHP ข้างต้นฝังอยู่ รหัสส่งได้อย่างสมบูรณ์ แต่ไม่เคยส่งอีเมล ฉันจะแก้ไขสิ่งนี้ได้อย่างไร


2
เป็นโปรแกรมของคุณในเครื่องคอมพิวเตอร์หรือโฮสต์สด
Tamil Selvan C

6
1. คุณแน่ใจหรือว่าไม่ได้เป็นสแปมของคุณ 2. คุณมี sendmail ที่ตั้งค่าไว้ในกล่องของคุณหรือไม่?
Steven Moseley

มันอยู่ในโฮสต์สดมันไม่ไปสู่สแปมของฉัน .. ฉันไม่แน่ใจว่าคุณหมายถึงอะไรโดยมี sendmail ที่ตั้งค่าไว้ในกล่องของฉัน
user3818620

ลองส่งโดยไม่ต้อง$from
Artem Ilchenko

คำตอบ:


512

แม้ว่าจะมีบางส่วนของคำตอบนี้ที่ใช้กับการใช้งาน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()ฟังก์ชั่นเป็นประโยชน์และมักจะได้รับงานทำ แต่ก็มีข้อบกพร่องของตน โชคดีที่มีทางเลือกที่ให้พลังงานและความยืดหยุ่นที่มากขึ้นรวมถึงการจัดการปัญหาต่าง ๆ ที่กล่าวถึงข้างต้น

  • สิ่งที่ได้รับความนิยมสูงสุด: PHPMailer
  • ฟีเจอร์เช่นเดียวกัน: SwiftMailer
  • หรือแม้กระทั่งพี่ลูกแพร์ :: จดหมาย

ทั้งหมดนี้สามารถใช้ร่วมกับเซิร์ฟเวอร์ SMTP / ผู้ให้บริการมืออาชีพ (เนื่องจากเว็บโฮสต์ที่ใช้ร่วมกันโดยทั่วไปของแผน 08/15 นั้นได้รับผลกระทบหรือพลาดเมื่อมีการตั้งค่า / กำหนดค่าอีเมล)


11
เขียนได้ดีมากจอห์น ฉันจะเพิ่มอีกหนึ่งสิ่ง: การตรวจสอบบันทึกเซิร์ฟเวอร์อีเมลของเซิร์ฟเวอร์อีเมลที่ส่ง (ไม่ว่าจะอยู่ในพื้นที่หรือโฮสต์จากระยะไกล) ถ้าเป็นไปได้มักจะทำให้กระจ่างในสิ่งที่ทำให้เกิดปัญหา บันทึกเหล่านี้ควรแสดง 1) ระบุว่าได้รับข้อความจากสคริปต์ PHP จากเซิร์ฟเวอร์อีเมลที่ส่งหรือไม่และถ้าเป็นเช่นนั้น 2) ว่า MX ได้รับการตอบรับจากเซิร์ฟเวอร์อีเมลที่ส่งหรือไม่
mti2935

@ mti2935 มีประโยชน์มากฉันประหลาดใจที่ฉันพลาด ฉันจะแน่ใจว่าจะเพิ่มมันในไม่ช้า :)
John Conde

1
ฉันจะเริ่มต้นด้วยการไม่ใช้งานmail()มันทำงานได้ไม่ดีและยากที่จะทำการดีบักได้ดีกว่า

1
เว็บไซต์เดียวกันบน 000webhost ส่งอีเมลได้สำเร็จและรวดเร็วบนโดเมน netai.net แต่บนเว็บไซต์ 88.net ฉันมีเว็บไซต์เดียวกันฉันได้รับในคอนโซลที่ข้อความส่งสำเร็จ แต่ฉันไม่ได้รับข้อความใด ๆ นอกจากนี้ในโดเมน comuf.com ฉันได้รับข้อผิดพลาด (เว็บไซต์เดียวกันบนโฮสต์เดียวกันใช้งานได้เฉพาะบนโดเมน netai.net, net16.net ก็ทำงานด้วย)
Nicolas Papaconstantinou

1
คำถามของฉัน ( stackoverflow.com/questions/44866673/ … ) ถูกทำเครื่องหมายว่าซ้ำกับคำถามนี้ แต่ฉันยังไม่สามารถเข้าใจได้ ข้อเสนอแนะใด ๆ
Zachary Elkins

37

เพิ่มส่วนหัวจดหมายในฟังก์ชั่นจดหมาย:

$header = "From: noreply@example.com\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>';
}

25
  1. ลองส่งส่วนหัวในฟังก์ชั่นจดหมาย
  2. หากคุณส่งจดหมายผ่าน localhost ให้ทำการตั้งค่า SMTP สำหรับส่งจดหมาย
  3. หากคุณกำลังส่งอีเมลผ่านเซิร์ฟเวอร์ให้ตรวจสอบว่าคุณสมบัติการส่งอีเมลนั้นเปิดใช้งานอยู่บนเซิร์ฟเวอร์ของคุณ

20

หากคุณใช้การกำหนดค่า SMTP สำหรับส่งอีเมลให้ลองใช้PHPMailerแทน คุณสามารถดาวน์โหลดห้องสมุดจากhttps://github.com/PHPMailer/PHPMailer

ฉันสร้างอีเมลที่ส่งด้วยวิธีนี้:

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 = "me@walalang.com";
    $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";
}

2
ฉันยังต้องใช้: ต้องการ ("phpmailer / class.smtp.php");
Doug

15

เพียงเพิ่มบางส่วนก่อนส่งอีเมล:

<?php 
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com'; 
$to = 'contact@yoursite.com'; 
$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: from@example.com' . "\r\n" .
'Reply-To: reply@example.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();

mail($to, $subject, $message, $headers);

และอีกสิ่งหนึ่ง mail()ฟังก์ชั่นที่ไม่ได้ทำงานใน localhost อัปโหลดรหัสของคุณไปยังเซิร์ฟเวอร์และลอง


1
สิ่งนี้ทำให้แบบฟอร์มส่ง - คำถามของฉันตอนนี้จะเป็น .. ฉันจะแสดงผู้ใช้ที่พิมพ์ในอีเมลได้อย่างไรตอนนี้ฉันได้แทนที่ด้วยส่วนหัว ...
user3818620

มันจะป้องกันจดหมายจากโฟลเดอร์สแปม ฉันได้เห็นว่าเราส่งจดหมายมากกว่า 10 รายการโดยใช้วิธีการนี้ที่คุณใช้ในรหัส gmail ของคุณส่งจดหมายนี้ไปยังจดหมายขยะ
jewelhuq

OP มีบรรทัดนี้: $from = 'From: yoursite.com'; ซึ่งไม่เหมือนกับที่อยู่อีเมลที่ถูกต้องสมบูรณ์ไม่มีส่วนในประเทศ คุณได้แทนที่ส่วนหัวจากและเพิ่มรายการเพิ่มเติมแล้ว หรือค่อนข้าง$fromด้านบนซ้ำซ้อนในตัวอย่างของคุณ และการผิดรูปแบบอาจเป็นปัญหาดั้งเดิมของ OP
Progrock

13

มันทำงานให้ฉันใน 000webhost โดยทำสิ่งต่อไปนี้:

$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";

ป้อนที่อยู่อีเมลโดยตรงเมื่อส่งอีเมล:

mail('email@gmail.com', $subject, $message, $headers)

การใช้งานและไม่ได้''""

รหัสนี้ใช้งานได้ แต่ได้รับอีเมลพร้อมความล่าช้าครึ่งชั่วโมง


10

mail()ฟังก์ชั่นส่วนใหญ่ถูกปิดการใช้งานในพื้นที่สาธารณะ ตัวเลือกที่ดีกว่าคือการใช้ SMTP ตัวเลือกที่ดีที่สุดคือ Gmail หรือ 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();
}
?>

เป็นความคิดที่ดีหรือไม่ที่จะบันทึกผู้ใช้ smtp และรหัสผ่านเป็นข้อความธรรมดาบนเซิร์ฟเวอร์?
Juri

@Juri อาจไม่ ... พระเจ้าฉันไม่สามารถหาวิธีใช้ฟังก์ชันเมลให้ทำงาน:. (

9

หากคุณใช้mail()ฟังก์ชั่นเพียงอย่างเดียวคุณจะต้องทำไฟล์กำหนดค่าให้เสร็จ

คุณต้องเปิดการขยายเมลและตั้งค่าSMTP smtp_portและอื่น ๆ และที่สำคัญที่สุดคือชื่อผู้ใช้และรหัสผ่านของคุณ หากไม่มีสิ่งนั้นเมลจะไม่สามารถส่งได้ นอกจากนี้คุณสามารถใช้PHPMailคลาสเพื่อส่ง


9

ลองสองสิ่งแยกกันและรวมกัน:

  1. ลบ if($_POST['submit']){}
  2. ลบ$from(เพียงไส้ในของฉัน)

8

ฉันคิดว่าสิ่งนี้ควรทำเคล็ดลับ ฉันเพิ่งเพิ่มif(issetและเพิ่มการต่อกันของตัวแปรในเนื้อความเพื่อแยก PHP ออกจาก HTML

<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];
    $from = 'From: yoursite.com'; 
    $to = 'contact@yoursite.com'; 
    $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>'; 
    }
}

?>

8

mailสำหรับทุกคนที่พบนี้ไปข้างหน้าไปผมจะไม่แนะนำให้ใช้ มีบางคำตอบที่สัมผัสกับสิ่งนี้ แต่ไม่ใช่สาเหตุของมัน

mailฟังก์ชั่นของ PHP ไม่เพียง แต่ทึบ แต่ก็ขึ้นอยู่กับว่าคุณใช้MTAใด(เช่นSendmail ) ในการทำงาน mailจะเพียงบอกคุณถ้าเอ็มทีล้มเหลวที่จะยอมรับมัน (เช่น Sendmail ลดลงเมื่อคุณพยายามที่จะส่ง) ไม่สามารถบอกคุณได้ว่าเมลนั้นประสบความสำเร็จหรือไม่เพราะมันถูกส่งไป เช่น (เช่นรายละเอียดคำตอบของ John Conde ) ตอนนี้คุณก็จะได้รู้ว่ามีบันทึกของ MTA และหวังว่ามันจะบอกคุณมากพอเกี่ยวกับความล้มเหลวในการแก้ไข หากคุณอยู่ในโฮสต์ที่ใช้ร่วมกันหรือไม่มีสิทธิ์เข้าถึงบันทึก MTA แสดงว่าคุณไม่มีโชค น่าเศร้าที่ค่าเริ่มต้นสำหรับวานิลลาส่วนใหญ่ที่ติดตั้งสำหรับ Linux จัดการด้วยวิธีนี้

จดหมายห้องสมุด ( PHPMailer , Zend Framework 2+, ฯลฯ ), mailการทำบางสิ่งที่แตกต่างจาก พวกเขาเปิดซ็อกเก็ตโดยตรงไปยังเซิร์ฟเวอร์อีเมลที่รับแล้วส่งคำสั่งอีเมล SMTP โดยตรงผ่านซ็อกเก็ตนั้น กล่าวอีกนัยหนึ่งคลาสทำหน้าที่เป็น MTA ของตัวเอง (โปรดทราบว่าคุณสามารถบอกให้ห้องสมุดใช้mailในการส่งอีเมลในที่สุด แต่ฉันขอแนะนำให้คุณอย่าทำเช่นนั้น)

ซึ่งหมายความว่าคุณสามารถดูการตอบสนองจากเซิร์ฟเวอร์ที่รับได้โดยตรง (ใน PHPMailer ตัวอย่างเช่นคุณสามารถเปิดใช้งานการดีบักเอาต์พุต ) ไม่ต้องเดาอีกต่อไปหากอีเมลไม่สามารถส่งได้หรือเพราะอะไร

หากคุณใช้ SMTP (เช่นคุณกำลังโทรหาisSMTP()) คุณสามารถรับบทบรรยายโดยละเอียดของการสนทนา SMTP โดยใช้SMTPDebugคุณสมบัติได้

ตั้งค่าตัวเลือกนี้โดยรวมบรรทัดลักษณะนี้ไว้ในสคริปต์ของคุณ:

$mail->SMTPDebug = 2;

คุณจะได้รับประโยชน์จากอินเทอร์เฟซที่ดีกว่า เมื่อmailคุณต้องตั้งค่าส่วนหัวของคุณสิ่งที่แนบมา ฯลฯ ด้วยห้องสมุดคุณจะมีฟังก์ชั่นเฉพาะสำหรับการทำเช่นนั้น นอกจากนี้ยังหมายถึงฟังก์ชั่นกำลังทำส่วนที่ยุ่งยากทั้งหมด (เช่นส่วนหัว)


6
$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>";
}

6

คุณสามารถใช้การตั้งค่าอีเมลโดยCodeIgniter ตัวอย่างเช่นการใช้SMTP (วิธีง่าย ๆ ):

$config = Array(
        'protocol' => 'smtp',
        'smtp_host' => 'mail.domain.com', // Your SMTP host
        'smtp_port' => 26, // Default port for SMTP
        'smtp_user' => 'name@domain.com',
        'smtp_pass' => 'password',
        'mailtype' => 'html',
        'charset' => 'iso-8859-1',
        'wordwrap' => TRUE
);
$message = 'Your msg';
$this->load->library('email', $config);
$this->email->from('name@domain.com', 'Title');
$this->email->to('emaildestination@domain.com');
$this->email->subject('Header');
$this->email->message($message);

if($this->email->send()) 
{
   // Conditional true
}

มันใช้งานได้สำหรับฉัน!


1
fsockopen () [function.fsockopen]: php_network_getaddresses: getaddrinfo ล้มเหลว: ไม่รู้จักโฮสต์ดังกล่าว - หากฉันพบข้อผิดพลาดนี้แล้วอะไรคือเหตุผลและสิ่งที่ต้องทำ?
Choudhury Saadmaan Mahmid

1
"ใช้งานได้สำหรับฉัน" เป็นเพียงข้อมูลเล็ก ๆ น้อย ๆ แต่ไม่ได้อธิบายอะไรมากนัก รหัสผ่านพอร์ตและ smtp จะทำให้เข้าใจผิดสำหรับผู้ใช้ส่วนใหญ่
มาริโอ

อะไรคือ"การกำหนดค่าอีเมล" ? คุณมีข้อมูลอ้างอิงหรือไม่?
ปีเตอร์มอร์เทนเซ่น

4

ลองสิ่งนี้

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

4

บางทีปัญหาคือการกำหนดค่าเซิร์ฟเวอร์อีเมล เพื่อหลีกเลี่ยงปัญหาประเภทนี้หรือคุณจะได้ไม่ต้องกังวลเกี่ยวกับปัญหาเซิร์ฟเวอร์อีเมลผมขอแนะนำให้คุณใช้PHPMailer

มันเป็นปลั๊กอินที่มีทุกสิ่งที่จำเป็นในการส่งจดหมายและสิ่งเดียวที่คุณต้องคำนึงถึงคือเปิดใช้พอร์ต SMTP (พอร์ต: 25 และ 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 = 'correo@gmail.com';
    $mail->Password = 'contrasenia';
    $mail->SMTPSecure = 'ssl';
    $mail->Port = 465;

    // Recipients
    $mail->setFrom('correo@gmail.com', 'my name');
    $mail->addAddress('destination@correo.com');

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

1
IANA ได้แทนที่พอร์ต 465 โดยพอร์ต 587 นี่คือพอร์ตการส่งเมลเริ่มต้น เมื่อไคลเอนต์อีเมลหรือเซิร์ฟเวอร์ขาออกกำลังส่งอีเมลเพื่อกำหนดเส้นทางโดยเซิร์ฟเวอร์อีเมลที่เหมาะสมควรใช้พอร์ต SMTP 587 เป็นพอร์ตเริ่มต้นเสมอ ดูmailgun.com/blog/which-smtp-port-understanding-ports-25-465-587 คำแนะนำที่ฉลาด: อย่าเปิดพอร์ตบนคอมพิวเตอร์ของคุณหากคุณไม่ได้ตระหนักถึงสิ่งที่คุณกำลังทำอยู่!
อันตราย

3

ตรวจสอบให้แน่ใจว่าคุณได้ติดตั้ง Sendmail ไว้ในเซิร์ฟเวอร์ของคุณ

หากคุณตรวจสอบรหัสของคุณและยืนยันว่าไม่มีอะไรผิดปกติให้ไปที่ / var / mail และตรวจสอบว่าโฟลเดอร์นั้นว่างเปล่าหรือไม่

หากว่างเปล่าคุณจะต้องทำสิ่งต่อไปนี้

sudo apt-get install sendmail

ถ้าคุณอยู่บนเซิร์ฟเวอร์ Ubuntu


นั่นเป็นวิธีที่หยาบเกินไปที่จะเป็นประโยชน์ การติดตั้ง MTA แทบจะไม่ได้รับอนุญาต และคู่มือการตั้งค่า sendmail / postfix / qmail เต็มรูปแบบจะเป็นหัวข้อที่นี่
มาริโอ

ความคิดเห็นนี้เกี่ยวข้องกับคำตอบของฉันหรือไม่ เพราะสิ่งนี้ไม่ได้เกิดขึ้นกับฉันและฉันก็ไม่ได้แก้อย่างนี้เหมือนกัน มีหลายคำตอบที่เป็นไปได้สำหรับคำถามฉันเป็นหนึ่งในพวกเขาหลังจากที่ได้ลองทั้งหมดข้างต้นในอดีตที่ผ่านมาคำตอบของฉันได้แก้ปัญหาให้ฉันแล้ว
แดเนียล

แน่นอน. เป็นหนึ่งในคำตอบที่เป็นไปได้มากมาย อย่างไรก็ตามมันยังคงเป็นวิธีการ IMO ผิวเผิน การสรุปลงใน "คุณต้องมี MTA" เช่น ... - และนี่คือคำแนะนำในการตั้งค่าบางอย่างที่เชื่อมโยง ... อาจเป็นประโยชน์มากกว่า
มาริโอ

3

ก่อนอื่นคุณอาจมีพารามิเตอร์มากเกินไปสำหรับฟังก์ชัน mail () ... คุณสามารถมีได้สูงสุดห้ารายการ mail(to, subject, message, headers, parameters);

เท่าที่$fromตัวแปรไปโดยอัตโนมัติควรมาจากเว็บโฮสต์ของคุณถ้าใช้ลินุกซ์ของคุณcPanel มันมาจากชื่อผู้ใช้ cPanel และที่อยู่ IP ของคุณโดยอัตโนมัติ

$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = 'contact@yoursite.com';
$subject = 'Customer Inquiry';
$body = "From: $name\n E-Mail: $email\n Message:\n $message";

ตรวจสอบให้แน่ใจว่าคุณมีลำดับที่ถูกต้องของตัวแปรในฟังก์ชัน mail () ของคุณ

mail($to, $subject, $message, etc.)ในลำดับที่หรืออื่น ๆ ที่มีโอกาสของมันไม่ได้ทำงาน


3

หากคุณมีปัญหาในการส่งอีเมลด้วย PHP ให้พิจารณาทางเลือกอื่นเช่นPHPMailerหรือSwiftMailer SwiftMailer

ฉันมักจะใช้ SwiftMailer ทุกครั้งที่ฉันต้องการส่งอีเมลด้วย PHP


การใช้งานขั้นพื้นฐาน:

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('jane.doe@gmail.com' => 'Jane Doe'))
    // The to address(es)
    ->setTo(array('frank.stevens@gmail.com' => '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);
}

ดูเอกสารประกอบอย่างเป็นทางการสำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีใช้ SwiftMailer


3

สำหรับผู้ที่ไม่ต้องการใช้เมลภายนอกและต้องการเมล () บนเซิร์ฟเวอร์ลินุกซ์โดยเฉพาะ

วิธีการอธิบายถึงวิธีอีเมล PHP php.iniในหัวข้อ[mail function]ในส่วน

พารามิเตอร์sendmail-pathอธิบายวิธีเรียกใช้ sendmail ค่าเริ่มต้นคือsendmail -t -iดังนั้นหากคุณได้รับการทำงานsendmail -t -i < message.txtในคอนโซล Linux - คุณจะทำ คุณสามารถเพิ่มmail.logในการแก้ปัญหาและให้แน่ใจว่า mail () ถูกเรียกจริงๆ

MTA ที่ต่างกันสามารถนำsendmailไปใช้ได้ พวกเขาเพียงแค่สร้างลิงก์สัญลักษณ์ไปยังไบนารีของพวกเขาในชื่อนั้น ยกตัวอย่างเช่นในDebianเริ่มต้นคือPostfix กำหนดค่า MTA sendmail -v -t -i < message.txtของคุณในการส่งจดหมายและการทดสอบได้จากคอนโซลด้วย ไฟล์message.txtควรมีส่วนหัวทั้งหมดของข้อความและเนื้อหาที่อยู่ปลายทางสำหรับซองจดหมายจะถูกนำมาจากTo:ส่วนหัว ตัวอย่าง:

From: myapp@example.com
To: mymail@example.com
Subject: Test mail via sendmail.

Text body.

ฉันชอบที่จะใช้ssmtpเป็น MTA เพราะมันง่ายและไม่ต้องใช้ daemon ด้วยพอร์ตที่เปิด ssmtp เหมาะสำหรับการส่งจดหมายจากlocalhostเท่านั้น นอกจากนี้ยังสามารถส่งอีเมลรับรองความถูกต้องผ่านทางบัญชีของคุณในบริการไปรษณีย์สาธารณะ การติดตั้งและการกำหนดค่า ssmtp /etc/ssmtp/ssmtp.confแก้ไขไฟล์ เพื่อให้สามารถรับเมลของระบบโลคัลไปยังบัญชี Unix (เช่นแจ้งเตือนไปยังรูทจากงาน cron เป็นต้น) กำหนดค่า/etc/ssmtp/revaliasesไฟล์

นี่คือการกำหนดค่าของฉันสำหรับบัญชีของฉันในจดหมาย Yandex:

root=mymail@example.com
mailhub=smtp.yandex.ru:465
FromLineOverride=YES
UseTLS=YES
AuthUser=abcde@yandex.ru
AuthPass=password

2

การดำเนินการนี้จะส่งผลกระทบต่อผู้ใช้เพียงไม่กี่คนเท่านั้น แต่ฉันต้องการให้มีการบันทึกไว้เพียงเล็กน้อยเท่านั้น สมาชิกกลุ่มเล็ก ๆ กลุ่มนี้ใช้เวลา 6 ชั่วโมงในการแก้ไขปัญหาสคริปต์จดหมาย PHP ที่ใช้งานได้เนื่องจากปัญหานี้

หากคุณกำลังจะไปมหาวิทยาลัยที่รัน XAMPP จาก www.AceITLab.com คุณควรรู้ว่าอาจารย์ของเราไม่ได้บอกเรา: ไฟร์วอลล์ AceITLab (ไม่ใช่ไฟร์วอลล์ Windows) บล็อก MercuryMail ใน XAMPP คุณจะต้องใช้โปรแกรมรับส่งเมลอื่นลูกแพร์เหมาะสำหรับเรา คุณจะต้องส่งไปยังบัญชี Gmail ที่มีการตั้งค่าความปลอดภัยต่ำ

ใช่ฉันรู้ว่ามันไม่มีประโยชน์อะไรกับอีเมลโลกแห่งความจริง อย่างไรก็ตามจากสิ่งที่ฉันได้เห็นสภาพแวดล้อมทางวิชาการและโลกแห่งความเป็นจริงมักจะมีค่าเล็กน้อยเหมือนกัน


มันแปลกมากเกินไปและจะช่วยคนอื่นไม่ได้อีกแล้ว โปรดใช้ลิงก์ [ลบ] ใต้คำตอบของคุณ
มาริโอ

"ลูกแพร์" ในบริบทนี้คืออะไร? คุณหมายถึงPEARซึ่งเป็นที่เก็บซอฟต์แวร์ PHP หรือไม่ หรืออย่างอื่น? เช่นเพียร์ ?
Peter Mortensen

คุณหมายถึง"มีค่าน้อย"จริงๆหรือ มันเป็นสิ่งที่ต้องการหรือไม่ ทำไม?
Peter Mortensen

1

หากคุณใช้รหัสนี้ในเซิร์ฟเวอร์ท้องถิ่น (เช่นคอมพิวเตอร์ของคุณเพื่อจุดประสงค์ในการพัฒนา) รหัสดังกล่าวจะไม่ส่งอีเมลไปยังผู้รับ มันจะสร้าง.txtไฟล์ในโฟลเดอร์ชื่อmailoutputไฟล์ในโฟลเดอร์ชื่อ

ในกรณีที่คุณใช้บริการฟรีเช่น000webhostหรือhostingerผู้ให้บริการเหล่านั้นปิดการใช้งานmail()ฟังก์ชั่นเพื่อป้องกันการใช้งานอีเมล์ปลอมแปลงอีเมล์สแปม ฯลฯ ฉันต้องการให้คุณติดต่อพวกเขาเพื่อดูว่าพวกเขาสนับสนุนคุณสมบัตินี้หรือไม่

หากคุณแน่ใจว่าผู้ให้บริการรองรับฟังก์ชั่น mail () คุณสามารถตรวจสอบคู่มือ PHP นี้สำหรับการอ้างอิงเพิ่มเติม

จดหมาย PHP ()

ในการตรวจสอบสภาพอากาศที่บริการโฮสต์ของคุณรองรับฟังก์ชั่น mail () ลองใช้งานรหัสนี้(อย่าลืมเปลี่ยนที่อยู่อีเมลของผู้รับ) :

<?php
    $to      = 'nobody@example.com';
    $subject = 'the subject';
    $message = 'hello';
    $headers = 'From: webmaster@example.com' . "\r\n" .
        'Reply-To: webmaster@example.com' . "\r\n" .
        'X-Mailer: PHP/' . phpversion();

    mail($to, $subject, $message, $headers);
?>

1

การติดตั้ง Sendmailสำหรับ Debian 10.0.0 ('Buster') เป็นเรื่องจริงเล็กน้อย!

php.ini

[mail function]
sendmail_path=/usr/sbin/sendmail -t -i
; (Other directives are mostly windows)

การติดตั้งแพคเกจsendmailมาตรฐาน(อนุญาตให้ 'ส่ง'):

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

คำสั่งที่มีประโยชน์เบ็ดเตล็ด:

which sendmail                              # /usr/sbin/sendmail
which sendmailconfig                        # /usr/sbin/sendmailconfig
man sendmail                                # Documentation
systemctl restart sendmail                  # As and when required

การยืนยัน (ความสามารถในการส่ง)

echo "Subject: sendmail test" | sendmail -v <yourEmail>@gmail.com

ใช้เวลาประมาณ 5 นาที ถ้าอย่างนั้นฉันเสียเวลา 5 ชั่วโมง ... อย่าลืมตรวจสอบโฟลเดอร์สแปมของคุณ !


0

มีความเป็นไปได้หลายอย่าง:

  1. คุณกำลังประสบปัญหาเซิร์ฟเวอร์ เซิร์ฟเวอร์ไม่มีเซิร์ฟเวอร์จดหมายใด ๆ ดังนั้นอีเมลของคุณไม่ทำงานเนื่องจากรหัสของคุณไม่ถูกต้องและอีเมลใช้งานได้กับประเภท

  2. คุณไม่ได้รับค่าโพสต์ ลองรหัสของคุณด้วยค่าคงที่

  3. ใช้เมล SMTP เพื่อส่งเมล ...


0

คุณสามารถใช้ libmail: http://lwest.free.fr/doc/php/lib/index.php3?page=mail&lang=th

include "libmail.php";
$m = new Mail(); // Create the mail
$m->From($_POST['form']);
$m->To($_POST['to']);
$m->Subject($_POST['subject']);
$m->Body($_POST['body']);
$m->Cc($_POST['cc']);
$m->Priority(4);
// Attach a file of type 'image/gif' to be displayed in the message if possible
$m->Attach("/home/leo/toto.gif", "image/gif", "inline");
$m->Send(); // Send the mail
echo "Mail was sent:"
echo $m->Get(); // Show the mail source

5
สิ่งสำคัญที่ต้องพูดถึง: นี่เป็นเพียงเครื่องมือmail()ห่อหุ้มฟังก์ชั่น เพิ่มการสร้างข้อความและลูกเล่นบางอย่างเท่านั้น
มาริโอ

0

คุณสามารถดูข้อผิดพลาดของคุณโดย:

error_reporting(E_ALL);

และรหัสตัวอย่างของฉันคือ:

<?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 = 'someone@gmail.com';  // SMTP username
    $mail->Password = 'password';           // SMTP password
    $mail->SMTPSecure = 'tls';              // Enable encryption, 'ssl' also accepted

    $mail->From = 'someone@gmail.com';
    $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';
?>

1
SMTPDebug = 0ไม่เป็นประโยชน์ หรือ "รหัสผ่าน" ธรรมดากับ GMail คำตอบนี้ไม่ได้มีส่วนร่วมมากที่นี่
มาริโอ

-2

หากระบบ sendmail ของคุณใช้งานได้รหัสของคุณจะต้องแก้ไขดังนี้

<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];

    $header ="
Content-Type: text/html; charset=UTF-8\r\n
MIME-Version: 1.0\r\n
From: \"$name\" <$email>\r\n
Reply-To: no-reply@yoursite.com\r\n
X-Mailer: yoursite.com mailer\r\n
";

    $to = '"Contact" <contact@yoursite.com>'; 
    $subject = 'Customer Inquiry';
    $body =<<<EOB
<!DOCTYPE html>
<html>
    <body>
        $message
    </body>
</html>
EOB;

    if ($_POST['submit']) {
        if (mail ($to, $subject, $body, $header) !== false) { 
            echo '<p>Your message has been sent!</p>';
        } else { 
            echo '<p>Something went wrong, go back and try again!</p>'; 
        }
    }
?>

สิ่งนี้ช่วยให้คุณสามารถส่งอีเมลแบบ HTML

ที่น่าสนใจที่น่าสนใจ:

  1. เราสร้างสตริงหลายส่วนหัว (แต่ละบรรทัดคั่นด้วย \ r \ n);
  2. เราเพิ่มประเภทเนื้อหาเพื่อแสดงว่าเราส่งคืน HTML เพื่อให้คุณสามารถเขียนอีเมลได้ดีขึ้น (คุณสามารถเพิ่มโค้ด HTML ที่คุณต้องการรวมถึง CSS ไปยังข้อความของคุณตามที่คุณต้องการในหน้า HTML)

หมายเหตุ: <<<EOBไวยากรณ์ต้องการตัวทำเครื่องหมาย EOB ล่าสุดเริ่มต้นเมื่อ pf เริ่มต้นบรรทัดและไม่มีที่ว่างหรืออักขระใด ๆ หลังจากอัฒภาค

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.