จัดเตรียมวิธีการส่งและจัดคิวอีเมลแบบเชิงวัตถุ
มีความจำเป็นต้องส่งอีเมลในเกือบทุกโครงการ เช่น สำหรับฟังก์ชันการลงทะเบียนผู้ใช้หรือรีเซ็ตรหัสผ่าน อีเมลส่วนใหญ่ที่ส่งนั้นง่ายมาก ไม่จำเป็นต้องมีฟีเจอร์ที่ซับซ้อน เช่น การเข้ารหัส PGP ฯลฯ ไลบรารีนี้นำเสนอวิธีสร้างอีเมลดังกล่าวโดยไม่ต้องตั้งค่า PHPMailer (ไลบรารีพื้นฐาน) เพื่อส่งอีเมลหลายฉบับและแม้แต่เลื่อนการส่งอีเมลโดยใช้คิวที่ได้รับการสนับสนุนจากฐานข้อมูล - และทั้งหมดนี้อยู่ใน วิธีการเชิงวัตถุ
คุณสมบัติคือ:
EmailQueue
โครงการนี้ได้รับอนุญาตภายใต้ GNU LGPL 3.0
composer install technicalguru/email
คุณสามารถดาวน์โหลดแพ็คเกจซอร์สโค้ดได้จากหน้าเผยแพร่ GitHub
คลาสกลางสำหรับการกำหนดค่าคือ EmailConfig
มันเก็บข้อมูลที่จำเป็นทั้งหมด เริ่มจากโครงกระดูกพื้นฐานกันก่อน:
use TgEmailEmailConfig;
$config = new EmailConfig();
$config->setTimezone('Europe/Berlin');
$config->setDefaultSender('John Doe <[email protected]>');
$config->setSubjectPrefix('[MyAppName] ');
$config->setDebugAddress('[email protected]');
บรรทัดด้านบนสร้างการกำหนดค่าและบอกให้ใช้เขตเวลา Europe/Berlin
เมื่อจำเป็นต้องสร้างการประทับเวลา ขั้นตอนนี้จำเป็นเป็นหลักเมื่อมีการจัดคิวอีเมลและจำเป็นต้องบันทึกการประทับเวลา ค่านี้เป็นทางเลือกและมีค่าเริ่มต้นเป็น UTC
ถัดไป มีการกำหนดค่าที่อยู่ผู้ส่งเริ่มต้น ผู้ส่งเริ่มต้นจะถูกใช้เมื่ออีเมลเฉพาะที่จะส่งไม่ได้กำหนดที่อยู่ของผู้ส่ง การสร้างที่อยู่อีเมลมีคำอธิบายเพิ่มเติมด้านล่าง
คำนำหัวเรื่องจะใช้กับอีเมลทุกฉบับที่จะส่งในภายหลัง หัวเรื่องจะขึ้นต้นด้วยสตริงนี้ ค่าเริ่มต้นคือ NULL
และจะไม่แก้ไขหัวเรื่อง
จำเป็นต้องมีที่อยู่การแก้ไขเฉพาะเมื่อคุณต้องการส่งอีเมลทดสอบ
เรายังต้องบอกว่าเซิร์ฟเวอร์ SMTP ของเราอยู่ที่ไหน นี่คือวิธีที่คุณตั้งค่าเหล่านี้:
use TgEmailConfigSmtpConfig;
$host = 'smtp.example.com;
$port = 587;
$auth = TRUE;
$username = 'mySmtpUser';
$password = 'mySmtpPassword';
$secureOption = 'starttls';
$smtpConfig = new SmtpConfig($host, $port, $auth, $username, $password, $secureOption);
$config->setSmtpConfig($smtpConfig);
ตัวเลือกส่วนใหญ่อธิบายตนเองได้ $auth
บอก PHPMailer พื้นฐานว่าจะตรวจสอบสิทธิ์ด้วยข้อมูลรับรองผู้ใช้ที่กำหนดหรือไม่ $secureOption
ถูกกำหนดโดย PHPMailer
และจะต้องมีค่า smtps
หรือ starttls
ดูเอกสารประกอบ PHPMailer สำหรับข้อมูลเพิ่มเติม
คุณสมบัติทั้งหมดสามารถตั้งค่าได้โดยใช้ตัวตั้งค่า:
use TgEmailConfigSmtpConfig;
$smtpConfig = new SmtpConfig();
$smtpConfig->setHost('smtp.example.com');
$smtpConfig->setPort(587);
// continue setup...
ข้อมูลรับรองการตรวจสอบความถูกต้องยังสามารถตั้งค่าได้โดยใช้อินเทอร์เฟซ TgUtilsAuthCredentialsProvider
จากแพ็คเกจ technicalguru/utils
:
// Define here your provider
$provider = ...;
// Tell SMTP config
$smtpConfig->setCredentialsProvider($provider);
ตอนนี้ได้เวลาสร้างวัตถุ MailQueue
กลางของเราแล้ว:
use TgEmailEmailQueue;
$mailer = new EmailQueue($config);
คุณพร้อมที่จะส่งอีเมลฉบับแรกของคุณแล้ว
มีวิธีที่ง่ายและรวดเร็วในการตรวจสอบว่าการตั้งค่าของคุณทำงานอย่างถูกต้องหรือไม่:
$email = $mailer->createTestMail();
$rc = $mailer->send($email);
เราได้ตั้งค่าข้อกำหนดขั้นต่ำในการส่งอีเมล:
use TgEmailEmail;
$email = new Email();
$email
->setSubject('Hello World')
->addTo('[email protected]', 'John Doe')
->addBcc('[email protected]')
->setReplyTo('[email protected]')
->setBody(Email::TEXT, 'The text e-mail body')
->setBody(Email::HTML, '<p>The HTML e-mail body</p>');
// Will return FALSE when sending fails
$rc = $mailer->send($email);
แค่นั้นแหละ. ข้อมูลโค้ดด้านบนคือทั้งหมดที่คุณต้องการในโค้ดแอปพลิเคชันของคุณเพื่อส่งอีเมล การกำหนดค่าและการตั้งค่าจะถูกฝังไว้ที่ใดที่หนึ่งในการตั้งค่าโครงสร้างพื้นฐานของคุณ
การแนบไฟล์หรือฝังรูปภาพทำได้ง่าย คุณจะต้องมีไฟล์และสามารถอ่านได้บนระบบไฟล์:
use TgEmailAttachment;
$myFile = new Attachment(Attachment::ATTACHED, 'file.pdf', NULL, '/local/path/to/file.pdf', 'application/pdf');
$myImage = new Attachment(Attachment::EMBEDDED, 'img.png', 'img1', '/local/path/to/img.png', 'image/png');
$email
->addAttachment($myFile)
->addAttachment($myImage);
สังเกตพารามิเตอร์ที่สามของรูปภาพที่ฝัง โดยจะกำหนดรหัสเฉพาะภายในอีเมล HTML ของคุณซึ่งคุณสามารถใช้อ้างอิงได้
// Using the embedded image
$myHTML = '<img src="cid:img1">';
MailQueue
จะปล่อยให้ไฟล์แนบทั้งหมดของคุณไม่ถูกแตะต้องบนระบบไฟล์ของคุณ อย่างไรก็ตาม บางครั้งคุณอาจต้องการกำจัดไฟล์หลังจากที่คุณส่งอีเมลไปแล้ว ตัวสร้างรับข้อโต้แย้งเพิ่มเติมอีกสองข้อ:
$myFile = new Attachment(Attachment::ATTACHED, $filename, $cid, $path, $mimeType, TRUE, TRUE);
บูลีนแรกจะกระตุ้นให้ไฟล์ถูกลบหลังจากส่งอีเมลสำเร็จ บูลีนตัวที่สองบอกว่าสามารถลบไฟล์ได้หรือไม่เมื่อการส่งล้มเหลว การใช้พารามิเตอร์เหล่านี้ทำให้คุณไม่จำเป็นต้องดูแลไฟล์ชั่วคราวอีกต่อไป โดยเฉพาะอย่างยิ่งเมื่อพูดถึงการเข้าคิวและการเลื่อนการส่ง
MailQueue
รองรับสิ่งที่เรียกว่าโหมดเมล พวกเขาบอกวัตถุไปรษณีย์ว่าโดยทั่วไปแล้วควรปฏิบัติต่ออีเมลอย่างไร สิ่งนี้จะสะดวกสบายเมื่อคุณกำลังทดสอบการตั้งค่า เมื่อคุณอยู่ในสภาพแวดล้อมที่มีที่อยู่อีเมลจริง (เช่น สภาพแวดล้อมการทดสอบการยอมรับของผู้ใช้) หรือเมื่อส่งอีเมลจริงๆ นั้นไม่สมเหตุสมผลมากนัก
โหมดเหล่านี้มีอยู่:
EmailQueue::DEFAULT
- นี่เป็นการทำงานปกติ อีเมลทั้งหมดจะถูกส่งตามที่กำหนดไว้EmailQueue::BLOCK
- วิธีนี้จะป้องกันไม่ให้มีการส่งหรือจัดคิวเมล รหัสส่งคืนจะเป็น TRUE เสมอEmailQueue::REROUTE
- อีเมลทั้งหมดจะถูกส่งไปยังที่อยู่อื่น โดยปกติจะเป็นที่อยู่ของผู้ดูแลระบบหรือนักพัฒนา และผู้รับอีเมลที่กำหนดไว้จะถูกละเว้นEmailQueue::BCC
- อีเมลจะถูกส่งไปยังผู้รับที่ต้องการ แต่ที่อยู่เพิ่มเติมจะถูกตั้งค่าไว้ที่ BCCการบล็อกอีเมลทั้งหมดที่จะส่งหรือเข้าคิวนั้นค่อนข้างง่าย:
$mailer->setMailMode(EmailQueue::BLOCK);
สามารถใช้วิธีการเดียวกันนี้กับออบเจ็กต์ EmailConfig
ส่วนกลางได้
คุณต้องตั้งค่าการกำหนดค่า RerouteConfig
ในการกำหนดค่าหลัก คุณสามารถตั้งค่านี้ล่วงหน้าได้เมื่อสร้างออบเจ็กต์การกำหนดค่า หรือตั้งค่าทั้งหมดพร้อมกันเมื่อตั้งค่าโหมดเมล:
use TgEmailConfigRerouteConfig;
// Create the config
$subjectPrefix = '[Rerouted]';
$recipients = array('[email protected]');
$rerouteConfig = new RerouteConfig($subjectPrefix, $recipients);
// And set the mail mode
$mailer->setMailMode(EmailQueue::REROUTE, $rerouteConfig);
คุณต้องตั้งค่าการกำหนดค่า BccConfig
ในการกำหนดค่าหลัก คุณสามารถตั้งค่านี้ล่วงหน้าได้เมื่อสร้างออบเจ็กต์การกำหนดค่า หรือตั้งค่าทั้งหมดพร้อมกันเมื่อตั้งค่าโหมดเมล:
use TgEmailConfigBccConfig;
// Create the config
$recipients = array('[email protected]');
$bccConfig = new BccConfig($recipients);
// And set the mail mode
$mailer->setMailMode(EmailQueue::BCC, $bccConfig);
ข้อเสียเปรียบประการหนึ่งของการส่งอีเมลโดยตรงจากรหัสแอปพลิเคชันคือใช้เวลานาน ผู้ใช้ของคุณต้องรอให้การส่งเสร็จสิ้นก่อนจึงจะสามารถเห็นการตอบกลับจากแอปพลิเคชันของคุณ การเข้าคิวอีเมลเป็นวิธีแก้ปัญหาเนื่องจากการส่งถูกเลื่อนออกไป (เหมาะกับงาน cron) และผู้ใช้จะได้รับการตอบสนองของแอปพลิเคชันอย่างรวดเร็ว
คุณจะต้องมีวัตถุ TgDatabaseDatabase
เพื่อจัดคิวอีเมล มิฉะนั้น EmailQueue
จะส่งข้อยกเว้นเมื่อคุณพยายามจัดคิวอีเมล โปรดดูเอกสารประกอบ TgDatabaseDatabase
เกี่ยวกับวิธีการสร้างวัตถุ Database
ตั้งค่า EmailsDAO
และ EmailQueue
ตามดังนี้:
use TgEmailEmailsDAO;
$dao = new EmailsDAO($database);
$mailer = new EmailQueue($config, $dao);
เมลจะสร้างตารางคิวโดยอัตโนมัติหากไม่มีอยู่
เมื่อ EmailsDAO
พร้อมใช้งานแล้ว คุณสามารถจัดคิวอีเมลได้อย่างง่ายดาย:
// Create your email object here
$email = ...
// Queue it. Will return FALSE when sending fails
$rc = $mailer->queue($email);
คุณสามารถประมวลผลคิวในการโทรอื่นหรือระหว่าง cronjob:
$mailer->processQueue($maxSeconds);
อาร์กิวเมนต์ $maxSeconds
จะทำให้แน่ใจว่าการประมวลผลจะหยุดลงเมื่อถึงขีดจำกัดเวลา อาร์กิวเมนต์นี้เป็นทางเลือกและมีค่าเริ่มต้นที่ 60 วินาที
มีหลายวิธีในการสร้างที่อยู่อีเมล ส่วนประกอบการส่งจดหมายทั้งหมดใช้วัตถุ EmailAddress
คุณสามารถใช้วัตถุนี้เป็นอาร์กิวเมนต์ได้ทุกที่ที่คาดหวังที่อยู่อีเมล มีหลายวิธีในการสร้างวัตถุดังกล่าว
// From a string
$address = EmailAddress::from('[email protected]');
$address = EmailAddress::from('<[email protected]>');
$address = EmailAddress::from('John Doe <[email protected]>');
// From email string and name
$address = EmailAddress::from('[email protected]', 'John Doe');
// From another object
$obj = new stdClass;
$obj->name = 'John Doe';
$obj->email = '[email protected]';
$address = EmailAddress::from($obj);
// From another EmailAddress
$address = EmailAddress::from($anotherEmailAddressObject);
ซึ่งหมายความว่าคุณสามารถใช้รสชาติเหล่านี้เมื่อสร้างอีเมล:
$email->addTo('John Doe <[email protected]>');
$email->addTo('[email protected]', 'John Doe');
$email->addTo(array('John Doe <[email protected]>', $anotherEmailAddressObject, $obj);
ออบเจ็กต์การกำหนดค่าที่แนะนำข้างต้นยังสามารถสร้างได้โดยใช้สตริง JSON ออบเจ็กต์ หรืออาร์เรย์ที่เชื่อมโยง ตัวอย่างต่อไปนี้อธิบายออบเจ็กต์ JSON ในรูปแบบย่อ
SmtpConfig:
-----------
{
"host": "www.example.com",
"port": 587,
"debugLevel": 0,
"auth": true,
"secureOption": "starttls",
"charset": "utf8",
"credentials": {
"user": "username",
"pass": "password"
}
},
RerouteConfig:
--------------
{
"recipients": "[email protected]",
"subjectPrefix": "[Rerouted]"
},
BccConfig:
----------
{
"recipients": "[email protected]"
},
EmailConfig:
------------
{
"timezone": "Europe/Berlin",
"mailMode": "default",
"smtpConfig": {... see above ...},
"rerouteConfig": {... see above ...},
"bccConfig": {... see above ...},
"debugAddress": "[email protected]",
"defaultSender": "[email protected]",
"subjectPrefix": "[PHPUnitTest] "
}
แต่ละคลาสการกำหนดค่าจัดให้มีวิธีการคงที่ from()
ที่ใช้ประเภทเหล่านี้เป็นอาร์กิวเมนต์และส่งกลับวัตถุการกำหนดค่าเอง:
$smtpConfig = SmtpConfig::from($jsonStringOrObjectOrAssocArray);
$rerouteConfig = RerouteConfig::from($jsonStringOrObjectOrAssocArray);
$bccConfig = BccConfig::from($jsonStringOrObjectOrAssocArray);
$emailConfig = EmailConfig::from($jsonStringOrObjectOrAssocArray);
เป็นไปได้ที่จะส่งอาร์เรย์ของออบเจ็ก Email
ไปยังฟังก์ชัน send()
และ queue()
อย่างไรก็ตาม โดยเฉพาะอย่างยิ่งสำหรับการส่งอีเมล์ทันที คุณควรทราบว่าการดำเนินการนี้อาจใช้เวลาพอสมควร กลยุทธ์ที่ดีกว่าคือการเข้าคิวส่งจดหมายจำนวนมาก
การทดสอบ PHPUnit ส่วนใหญ่จะไม่ถูกดำเนินการเมื่อไม่มีเซิร์ฟเวอร์ SMTP หรือฐานข้อมูลที่พร้อมใช้งาน การทดสอบหน่วยจะตรวจสอบตัวแปรสภาพแวดล้อม EMAIL_TEST_SMTP
และ EMAIL_DATABASE
มีสคริปต์ทุบตี set-test-env.sh
ที่สร้างตัวแปรเหล่านั้นให้กับคุณ คัดลอกไปที่ เช่น set-local-test-env.sh
และทำตามคำแนะนำในไฟล์
รายงานจุดบกพร่อง ขอการปรับปรุง หรือดึงคำขอได้ที่ GitHub Issue Tracker