Gửi email trong PHP

Hôm nay mình sẽ trình bày với các bạn một số phương pháp gửi email trong PHP mà mình biết. Có thể nói là chức năng gửi email nó không quan trong nếu website của bạn không có sử dụng nó nhưng nếu website của bạn có sử dụng như là gửi contact, thông tin đặt hàng, thông tin đặt phòng, gửi email kích ...

Hôm nay mình sẽ trình bày với các bạn một số phương pháp gửi email trong PHP mà mình biết. Có thể nói là chức năng gửi email nó không quan trong nếu website của bạn không có sử dụng nó nhưng nếu website của bạn có sử dụng như là gửi contact, thông tin đặt hàng, thông tin đặt phòng, gửi email kích hoạt tài khoản..vv mà email không gửi được thì hậu quả là không lường. Hơn nữa nếu website của bạn là sản xuất cho khách hàng thì điều đó còn to lớn hơn nữa.

Một số phương pháp gửi email trong PHP.

  • Hàm mail.
  • Thư viện PHPMailer
  • Thư việc SendGrid
  • Thư việc SwiffMailer
  • ... Một số thư viên khác.

1. Hàm mail trong PHP

Có thể nói đây là cách đơn giản nhất giúp bạn có thể gửi một email tới một email khác bằng cách sử dụng hàm mail có sẵn trong lõi của PHP. 

// Địa chỉ email gửi
$from 	 = 'info@chiasephp.net'; 
// Địa chỉ email nhận
$to	 	= 'abc@gmail.com';
$branch	 = 'Your branch'; 
// Chủ đề của email
$subject = 'Chủ đề email'; 
// Nội dung email cần gửi tới mail người nhận
$message = 'Nội dụng email'; 
// Khai báo thông tin mail người gửi
$headers = 	"MIME-Version: 1.0
".
        "Content-type: text/html; charset=utf-8
".
        "From:  ".$branch."
".
        "Subject: ".$subject."
"; 
// Nếu việc gửi mail thành công sẽ báo TRUE hoặc FALSE
$is_send_mail = @mail($to, $subject, $message, $headers);

Ở đoạn code bên trên, việc gửi mail thật đơn giản. Nếu các bạn muốn gửi mail đến nhiều người hơn, thì có thể thêm địa chỉ email ở biến $to, hoặc chèn thêm cc: hoặc bcc: vào biến $headers, và mỗi email sẽ được ngăn cách bởi dấu phẩy.

Hàm mail trong PHP cũng cho phép bạn gửi email trong nội dung gửi có chứa mã HTML và gửi email kèm theo file đính kèm.

Nhưng theo cá nhân mình khi bạn sử dụng hàm mail trong PHP đthì sẽ gặp một số vấn đề vấn đề.

  • Tốc độ gửi email tương đối chậm chạp
  • Không gửi được mail mặc dù báo hàm mail trả về kết quả mail được gửi thành công
  • Hiện nay một số nhà cung cấp dịch vụ đã chặn hoặc off luôn hàm mail.
  • SPAM, Khó thoát khỏi bộ lọc spam của các của các nhà cung cấp dịch vụ như Google, Yahoo, Outlook.

2. Thư viện PHPMailer.

PHPMailer là một lớp(class) thư việc cho phép bạn tích hợp vào suorce code và gửi email từ ứng dụng của bạn. Và đây là một thư viện miễn phí tính tới thời điểm này.

Một số ưu điểm:

  • Gửi mail thông qua giao thức SMTP.
  • Dễ dàng chỉ định một địa chỉ email gửi là địa chỉ email cá nhân hoặc email bất kỳ.
  • Gửi mail nhanh ít lỗi mail được chuyển vào thằng vào inbox.
  • Có thể thêm cc,bcc, đính kèm file.
  • Hỗ trợ gửi HTML Email từ Scripts
  • Làm việc trên tất cả các nền Linux/BSD/Windows

Để bắt đầu sử dụng thì bạn phải tải thư viện tại PHPMailer về và giải nén ra và copy nó vào source code của bạn. Tải PHPMail

Lưu ý: Bạn phải include/require  nó vào source code của bạn.

require 'PHPMailerAutoload.php';

$mail = new PHPMailer;
//$mail->SMTPDebug = 3;                               // Enable SMTP debug
$mail->isSMTP();                                      // Thiết lập mailer sử dụng SMTP
$mail->CharSet  = "utf-8";
$mail->Host = 'smtp.gmail.com';  		      // SMTP servers
$mail->SMTPAuth = true;                               // Enable SMTP authentication
$mail->Username = 'user@example.com';                 // SMTP username
$mail->Password = 'password';                         // SMTP password
$mail->SMTPSecure = 'tls';                            // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587;                                    // TCP port to connect to

$mail->From = 'noreply@chiasephp.net';		      // Thiết lập địa chỉ email người gửi
$mail->FromName = 'Mailer';                           // Thiết lập tên người gửi
$mail->addAddress('info@chiasephp.net', 'Example');   // Địa chỉ email và tên người nhận
$mail->addAddress('sales@chiasephp.net');             // Tên người nhận là tuy chọn
$mail->addReplyTo('info@chiasephp.net', 'Example');   // Địa chỉ email và tên người nhận khi người nhận reply
$mail->addCC('cc@chiasephp.net');		      // Thêm CC 
$mail->addBCC('bcc@chiasephp.net');                   // Thêm BCC 

$mail->addAttachment('/var/tmp/file.tar.gz');         // Thêm file đính kèm
$mail->addAttachment('/tmp/image.jpg', 'new.jpg');    // Thêm file đính kèm với tên tùy chọn
$mail->isHTML(true);                                  // Gửi email với định dạng là HTML

$mail->Subject = 'Đây là chủ đề'; // Chủ đề email cần gửi
$mail->Body    = 'Đây là nội dung emaiil cần gửi có thể chưa mã HTML!'; // Nội dung email cần gửi

if(!$mail->send()) {
    echo 'Lỗi gửi thư.';
    echo 'Thông báo: ' . $mail->ErrorInfo;
} else {
    echo 'Thư gửi thành công';
}

Lưu ý:

  • $mail->Host: bạn có thể chỉ định một hay nhiều server email. Mỗi server email cách nhau bởi dấu (;).
  • $mail->SMTPSecure = 'tls' và $mail->Port = 587 thì bạn có thể sử dụng $mail->SMTPSecure = 'ssl' và $mail->Port=465.
  • $mail ->Username và $mail->Passowrd có thể sử dụng chỉnh địa chỉ gmail của bạn. 

Nhược điểm:

Nghe có vẻ hay nhưng trong quá trình sử dụng PHPMailer này mình cũng gặp không ít tình huống dở khóc, dở cười như sau

  • Email không gửi đi thành công(Mặc dù hàm mail->send() trả về là TRUE).
  • SMTP không kết nối được server mail (STMP not connect to host)
  • Nếu bạn sử dụng gmail thì tài khoản email gửi(sender) phải được xác mình hai lớp.
  • Khó gửi email thành công nếu địa chỉ email nhận là Yahoo, Outlook.
  • SPAM

3. SendGrid

Theo cá nhân mình thì đây là một dịch vụ mailer tuyệt vời. Bản thân mình đã sử dụng khoảng hai năm nay thấy nó khá ổn. Gửi email ít vào SPAM, hỗ trợ gửi email thông qua SMTP, API nhưng nó là một dịch vụ mà bạn phải trả phí.

Nhưng các bạn đừng sớm nản lòng vì hiện tạo SendGrid miễn phí gửi 12K email miễn phí hàng tháng.

Ngoài những ưu điểm của PHPMailer ra nó có thêm một số ưu và nhược điểm như sau:

  • Tốc độ gửi mail khá nhanh.
  • Hỗ trợ gửi email thông qua API
  • Công cụ dashboard quản lý chiến dịch marketing, campain, thống kê số lượng email gửi, nhận ...vv.
  • Dễ dàng tích hợp các nền tảng server mail khác.
  • Bạn phải trả phí hàng tháng.

P/s: Nhưng nếu ứng dụng của bạn không phải là quá lớn thì 12K email hàng tháng có thể hoàn toàn đáp ứng nhu cầu gửi email từ ứng dụng của bạn.

Các bước tính hợp SendGrid vào source code

Đầu tiền thì bạn truy cập vào website http://sendgrid.com/ của SendGrid và đăng ký một tài khoản.

Trong SendGrid có rất nhiều dịch vụ và công cụ cho bạn lựa chọn tuy nhiên trong bài viết này chúng ta chỉ quan tâm tới dịch vụ gửi email SMTP của nó.

SendGrid hỗ trợ bạn hai hình thức gửi email.

  • Gửi email bằng API
  • Gửi email bằng thư viện

3.1. Send email bằng API

Có thể nói nó quá đơn giản. Ngoài việc cung cấp cho nó các tham số đâu vào như email gửi, nhận...vv thì bạn cần lưu ý là phải cung cấp chính xác hai tham số là api_user và api_key thì hai tham số này là tên đăng nhập và mật khẩu bạn đăng ký với Sendgrid.

$url = 'https://api.sendgrid.com/'; // URL API	
$params = array(
    'api_user' => 'api_user', // Tài khoản bạn đăng ký với SendGrid
    'api_key' => 'api_key', // Password bạn đăng ký với SendGrid
    'to' => 'example@gmail.com', // Địa chỉ email nhận
    'replyto' => 'info@chiasephp.net', // Reply
    'subject' => 'Chủ đề email',  // Chủ đề email
    'html' => 'Nội dung cần gửi có mã HTML', // Nội dung có thể chứa mã HTML
    'text' => 'Nội dung cần gửi không có mã HTML', 
    'from' => 'info@chiasephp.net', // Địa chỉ email gửi
    'fromname' => 'Example' // Tên người gửi
);
$params['files[file.tar.gz]'] = "@/var/tmp/file.tar.gz";
#
$request = $url.'api/mail.send.json';
// Generate curl request
$session = curl_init($request);
// Tell curl to use HTTP POST
curl_setopt ($session, CURLOPT_POST, true);
// Tell curl that this is the body of the POST
curl_setopt ($session, CURLOPT_POSTFIELDS, $params);
// Tell curl not to return headers, but do return the response
curl_setopt($session, CURLOPT_HEADER, false);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
// obtain response
$response = curl_exec($session);
curl_close($session);
// print everything out
if(strpos($response,'success') != false)
    echo 'Gửi thư thành công.';
else
    echo 'Gửi thư thất bại.';

3.2. Send email bằng Thư viện.

Để có thể tải về thư viện của SendGrid thì bạn truy cập vào link Libraries của SendGrid và chọn lựa nền tảng bạn muốn tích hợp. Trong nội dung bài viết này thì mình chọn nền tảng là PHP. Hoặc bạn có thể truy cập ngay vào link thư viện của SendGrid trên Github để tải về.

Lưu ý: Bạn nên sử dụng composer để có thể tải về.

{
  "require": {
    "sendgrid/sendgrid": "~5.2"
  }
}
// Require thư viện vào ứng dụng của bạn
require_once('/SendGrid/vendor/autoload.php'); 

// Khởi tạo đối tượng SendGrid 
$SendGrid = new SendGrid('api_use','api_key', array("turn_off_ssl_verification" => true));
// Khởi tạo đối tượng mail
$mail = new SendGridEmail();
// Param send email
$mail->addTo('example@gmail.com') // Địa chỉ email nhận
      ->setFrom('noreply@chiasephp.net') // Địa chỉ email gửi
      ->setFromName('ChiasePHP.Net') // Tên người gửi
      ->setReplyTo('info@chiasephp.net') // Reply tới địa chỉ email này
      ->setSubject('Chủ đề email') // Chủ đề email
      ->setHtml('Nội dung email') // Nội dung có thể chứa mã HTML
      ->addHeader('X-Sent-Using', 'SendGrid-API')
      ->addHeader('X-Transport', 'web');
$mail->addAttachment('/var/tmp/file.tar.gz');
// obtain response
$response = @$SendGrid->send($mail);
if($response->body['message']=='success')
    echo 'Gửi thư thành công.';
else
    echo 'Gửi thư thất bại.';

4. Swift Mailer

Mình cũng sử dụng Swift Mailer và mình thấy rằng nó cũng có điểm tương đồng với PHPMailer. Tuy nhiên nó có điểm đặc biệt là nó có thể tích hợp PHPMailer và một số Server Mail khác vào nó.

Bạn có thể truy cập vào wesbite của Swift Mailer để tham khảo. Hoặc truy cập vào Github để tải thư viện Swift Mailer https://github.com/swiftmailer/swiftmailer.

require_once 'lib/swift_required.php';

// Create the Transport
$transport = Swift_SmtpTransport::newInstance('smtp.example.org', 25)
    ->setUsername('your username')
    ->setPassword('your password')
;

/*You could alternatively use a different transport such as Sendmail or Mail:

// Sendmail
$transport = Swift_SendmailTransport::newInstance('/usr/sbin/sendmail -bs');

// Mail
$transport = Swift_MailTransport::newInstance();*/

// Create the Mailer using your created Transport
$mailer = Swift_Mailer::newInstance($transport);

// Create a message
$message = Swift_Message::newInstance('Wonderful Subject')
    ->setFrom(['john@doe.com' => 'John Doe'])
    ->setTo(['receiver@domain.org', 'other@domain.org' => 'A name'])
    ->setBody('Here is the message itself');

// Send the message
$result = $mailer->send($message);

Ngoài các thư việc trên các bạn có thể tham khảo hai thư viện nữa đó là

  • Mandril
  • Mailgun

5. Tổng kết.

Trong bài viết này mình đã hướng dẫn các bạn làm thế nào để gửi email thành công trong PHP. Việc mà gửi email không thành công ngoài việc phụ thuộc vào hàm mail, hay các thư viện, Mail Server thì nó còn phụ thuộc vào địa chỉ email gửi, Server IP có nằm trong Black Lists hay không. Còn một lý do nữa là địa chỉ email nhận có đúng định dạng hay không? Vì vậy trước khi gửi email bạn cần kiểm tra email xem có đúng định dạng chuẩn(format) hay không?

Một số phương pháp kiểm tra email trong PHP.

1. Sử dụng hàm filter_var.

function is_valid_email($email) {
    $valid = true;
    if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
        $valid = false;
    }
    return $valid;
}

2. Sử dụng Regular expression

function is_valid_email($email){
	if ($email=="" || $email==null){
		return 0;
	}
	// Use regular expression to check valid email address
	$strRegular = "^[A-Za-z0-9_.-]+@[A-Za-z0-9_.-]+.";
	$strRegular = $strRegular . "[A-Za-z0-9_-][A-Za-z0-9_-]+$";
	if (!ereg($strRegular, $email)) {
		return 0;
	}		
	return 1;   	
}
    0