Jul
6

Gởi mail sử dụng PHPMailer trong CakePHP

Author admin    Category Chia sẻ     Tags , ,

Hôm nay tôi sẽ hướng dẫn các bạn gởi mail sử dụng PHPMailer thông qua component có tên SmtpEmail. Một số host họ disable hàm mail() của PHP nhằm ngăn chặn spam (ví dụ hosting của digipower), khi đó ta cần dùng một công cụ khác để gởi email, tôi thường dùng phpmailer (hỗ trợ gởi mail bằng smtp hoặc hàm mail() của PHP)

Đầu tiên, các bạn tải mã nguồn phpmailer về, giải nén và cho vào app/vendors

Download phpmailer

Tiếp đó các bạn tạo component smtp_email.php đặt trong app/controllers/components. Nội dung file này như sau:

<?php 
class SmtpEmailComponent {
  /**
   * Send email using SMTP Auth by default.
   */
  var $from         = 'cakephpvn@cakephpvn.org';
  var $fromName     = "Cake PHP-Mailer";
  var $Mailer = "mail";
  var $SMTPAuth = false;
  var $smtpUserName = '';  // SMTP username
  var $smtpPassword = ''; // SMTP password
  var $smtpHostNames= "localhost";
  var $smtpHostPort= "25";
  var $text_body = null;
  var $html_body = null;
  var $to = null;
  var $toName = null;
  var $subject = null;
  var $cc = null;
  var $bcc = null;
  var $template = 'email/default';
  var $attachments = null;
 
  var $controller;
 
  function startup( &$controller ) {
    $this->controller = &$controller;
  }
 
  function bodyText() {
    /** This is the body in plain text for non-HTML mail clients
     */
    ob_start();
    $temp_layout = $this->controller->layout;
    $this->controller->layout = '';  // Turn off the layout wrapping
    $this->controller->render($this->template . '_text');
    $mail = ob_get_clean();
    $this->controller->layout = $temp_layout; // Turn on layout wrapping again
    return $mail;
  }
 
  function bodyHTML() {
    /** This is HTML body text for HTML-enabled mail clients
     */
    ob_start();
    $temp_layout = $this->controller->layout;
    $this->controller->layout = 'email';  //  HTML wrapper for my html email in /app/views/layouts
    $this->controller->render($this->template . '_html');
    $mail = ob_get_clean();
    $this->controller->layout = $temp_layout; // Turn on layout wrapping again
    return $mail;
  }
 
  function attach($filename, $asfile = '') {
    if (empty($this->attachments)) {
      $this->attachments = array();
      $this->attachments[0]['filename'] = $filename;
      $this->attachments[0]['asfile'] = $asfile;
    } else {
      $count = count($this->attachments);
      $this->attachments[$count+1]['filename'] = $filename;
      $this->attachments[$count+1]['asfile'] = $asfile;
    }
  }
 
  function send() {    
    App::import('Vendor','PHPMailer', array('file'=>'phpmailer'.DS.'class.phpmailer.php'));
    $mail = new PHPMailer();
 
    $mail->Mailer = $this->Mailer;
    $mail->SMTPAuth = $this->SMTPAuth;     // turn on SMTP authentication
    $mail->Host   = $this->smtpHostNames;
    $mail->Port = $this->smtpHostPort;
    $mail->Username = $this->smtpUserName;
    $mail->Password = $this->smtpPassword;
 
    $mail->From     = $this->from;
    $mail->FromName = $this->fromName;
    $mail->AddAddress($this->to, $this->toName );
    $mail->AddReplyTo($this->from, $this->fromName );
 
    $mail->CharSet  = 'UTF-8';
    $mail->WordWrap = 50;  // set word wrap to 50 characters
 
    if (!empty($this->attachments)) {
      foreach ($this->attachments as $attachment) {
        if (empty($attachment['asfile'])) {
          $mail->AddAttachment($attachment['filename']);
        } else {
          $mail->AddAttachment($attachment['filename'], $attachment['asfile']);
        }
      }
    }
 
    $mail->IsHTML(true);  // set email format to HTML
 
    $mail->Subject = $this->subject;
    //$mail->Body    = $this->bodyHTML();
    //$mail->AltBody = $this->bodyText();
    $mail->Body    = $this->html_body;
    $mail->AltBody = $this->text_body;
 
    $result = $mail->Send();
    if($result == false ) $result = $mail->ErrorInfo;
    return $result;
  }
}
?>

Sử dụng trong controller (mã nguồn minh họa form gởi thông tin liên hệ, các bạn tự điều chỉnh thông tin cho phù hợp)

<?php
class ContactController extends AppController {
  var $components=array('SmtpEmail');
 
  function send() {
    if(!$this->Session->check('contact_has_been_sent')) {
      $email_content="";
      $data = $this->data['Contact'];
      $name = $data['name'];
      $company = $data['company'];
      $address = $data['address'];
      $phone = $data['phone'];
      $email = $data['email'];
      $content = $data['note'];
 
      if($name!="" && $email!="" && $address!="" && $content!="") {
        $email_content = "Thông tin liên hệ nhận được từ phía khách hàng<br /><br />";
        $email_content .= "<b>Họ và tên:</b> " .$name. "<br/>";
        $email_content .= "<b>Công ty:</b> " .$company. "<br/>";
        $email_content .= "<b>Địa chỉ:</b> " .$address. "<br/>";
        $email_content .= "<b>Điện thoại:</b> " .$phone. "<br/>";
        $email_content .= "<b>Email:</b> " .$email. "<br/>";
        $email_content .= "<b>Nội dung:</b> " .$content. "<br/>";
        $email_content .='<br />';
      }else {
        //do something here
      }
 
      $contact_email = cakephpvn@cakephpvn.org
 
      $this->SmtpEmail->from         = $email;
      $this->SmtpEmail->fromName     = $name;
      $this->SmtpEmail->subject = 'Thong tin lien he goi tu website cakephpvn.org';
      $this->SmtpEmail->Mailer = 'smtp';
      $this->SmtpEmail->SMTPAuth = true;
      $this->SmtpEmail->smtpHostNames= mail.cakephpvn.org;
      $this->SmtpEmail->smtpUserName = user;
      $this->SmtpEmail->smtpPassword = password;
      $this->SmtpEmail->html_body = $email_content;
 
      $this->SmtpEmail->to = $contact_email;
      $result = $this->SmtpEmail->send();
 
      $this->Session->write('contact_has_been_sent','sent');
     }else {
      //do something here
    }
    $this->redirect($this->referer());
  }
}
?>

Các bạn cần chú ý tới phần: smtpHostNames, smtpUserName, smtpPassword. Đây là các thông số kết nối tới smtp server

Component gốc nằm ở bài viết này: http://bakery.cakephp.org/articles/view/sending-email-with-phpmailer

Tôi đã chỉnh lại đôi chút khi áp dụng vào các dự án của mình

10 Comments to “Gởi mail sử dụng PHPMailer trong CakePHP”

  • Bảo Nam 28/09/2010 at 7:36 pm

    Bạn cho mình hỏi, việc dùng php mail chay gửi mail, mà dùng phpmailer thì khác nhau là điều gì vậy bạn (mình hơi gà về mail =.=”)

  • admin 06/10/2010 at 2:42 pm

    Có 2 lí do:

    - Một số host không cho dùng hàm mail()
    - phpmailer cho phép bạn gởi mail thông qua smtp nên bạn có thể để web ở hosting này nhưng dùng account email ở nơi khác để gởi mail trên cái web đó
    - phpmailer cho phép dùng template để gởi mail, bạn có thể tạo ra các email có giao diện đẹp thay vì text đơn thuần

  • long 20/04/2011 at 1:18 am

    Hi
    mình đã dùng cái này để send mail nhưng bị lỗi

    Cannot modify header information – headers already sent by (output started at E:\wordpress\wamp\www\Share-ebook\cake\libs\debugger.php:673) [CORE\cake\libs\controller\controller.php

    pls help me !

  • admin 20/04/2011 at 4:37 pm

    Nếu bạn không dùng cái này để gởi email thì có bị lỗi gì không? Lỗi này do đã có 1 hoặc nhiều ký tự nào đó xuất ra trước hàm header của bạn hoặc của cake, bạn kiểm tra lại xem nó bị lỗi khi dùng component send email hay chỗ khác nhé!

    • MINHKHANG 22/08/2011 at 11:35 am

      Parse error: syntax error, unexpected ‘@’ in /home/hoangson/domains/minhkhang.org/public_html/vpp/components/com_contact/index.html.php on line 29

      Line 29 : $contact_email = mail@minhkhang.org

  • admin 04/09/2011 at 6:35 pm

    Vì câu thông báo lỗi nên dẫn tới cannot modify header information

    Nếu trong code bạn viết:

    $contact_email = mail@minhkhang.org

    thì đã bị sai cú pháp rồi, phải là:

    $contact_email = ‘mail@minhkhang.org’;

  • vinh 09/01/2012 at 10:25 pm

    (!$this->Session->check(‘contact_has_been_sent’))
    Bạn cho mình hỏi cái này ở đâu vậy, có phải view có nút check ko
    Bạn có cho mình xem cái view send mail của bạn dc ko, mình cảm ơn

    • admin 26/02/2012 at 1:29 am

      Cái đoạn:

      if(!$this->Session->check(‘contact_has_been_sent’)) {

      }

      mình dùng để chặn việc ai đó submit liên tục cái form của mình, mỗi khi gởi xong 1 liên hệ, mình write session đánh dấu đã gởi rồi, khi nào session hết hạn mới cho gởi tiếp.

  • maiphuong 17/02/2012 at 3:14 pm

    chào bạn ! bạn cho mình hỏi gửi mail theo form có sẳn thì bắt đầu làm từ đâu, như thế nào ah.host bị disable hàm mail .

  • admin 26/02/2012 at 1:26 am

    Form có sẵn là sao bạn? Nếu host bị disable hàm mail thì chỉ có thể dùng stmp. PHPMailer là tool ok!

Post comment

Follow us on Twitter! Follow us on Twitter!
Diễn đàn CakePHP cho người Việt Nam

Bài viết mới

Thảo luận mới

TAG

Calendar

July 2010
M T W T F S S
« Jun   Aug »
 1234
567891011
12131415161718
19202122232425
262728293031  

Lưu trữ

Blogroll

Thống kê

7 khách