Tìm kiếm bài viết

Laravel: Mail (Phần 1)

12.10.2020

0/5 (0 Reviews)

Gửi mail trong Laravel cung cấp API rất đơn giản thông qua thư viện với drivers SMTP, Mailgun, SparkPost, Amazon SES, hàm mail của PHP, và sendmail.

    Giới thiệu về gửi Mail trong Laravel

    Laravel cung cấp API rất đơn giản thông qua thư viện với drivers SMTP, Mailgun, SparkPost, Amazon SES, hàm mail của PHP, và sendmail, cho phép bạn nhanh chóng bắt đầu gửi mail qua dịch vụ mail local hay cloud tuỳ theo lựa chọn của bạn.

    Tìm hiểu các loại Driver Prerequisites

    Các API dựa trên driver như Mailgun và SparkPost thường đơn giản và nhanh hơn SMTP server. Nếu có thể, bạn nên sử dụng trong những dirver này. Tất cả các API driver yêu cầu sử dụng thư viện Guzzle HTTP có thể cài đặt thông qua Composer:

    composer require guzzlehttp/guzzle
    

    Mailgun Driver

    Để sử dụng Mailgun driver, đầu tiên cần cài Guzzle, sau đó cấu hình driver trong file config/mail.php vào mailgun. Tiếp theo, xác định rằng file config/services.php của bạn cấu hình theo options:

    'mailgun' => [
        'domain' => 'your-mailgun-domain',
        'secret' => 'your-mailgun-key',
    ]
    

    SparkPost Driver

    Để sử dụng SparkPost driver, đầu tiên cần phải cài đặt Guzzle, sau đó tùy chỉnh driver trong file cấu hình config/mail.php vào sparkpost. Tiếp theo, bạn phải cấu hình file config/services.php theo options sau:

    'sparkpost' => [
        'secret' => 'your-sparkpost-key',
    ],
    

    SES Driver

    Để sử dụng Amazon SES driver bạn cần phải cài đặt Amazon AWS SDK cho PHP. Bạn có thể cài đặt thư viện này bằng cách thêm 1 dòng vào phần require trong file composer.json và chạy lệnh composer update:

    "aws/aws-sdk-php": "~3.0"
    

    Tiếp theo, đặt tùy chỉnh driver trong file config/mail.php vào ses và xác định file cấu hình config/services.php được cấu hình theo options:

    'ses' => [
        'key' => 'your-ses-key',
        'secret' => 'your-ses-secret',
        'region' => 'ses-region',  // e.g. us-east-1
    ],
    

    Tìm hiểu Generating Mailables

    Trong Laravel, mỗi loại email được gửi đi bởi ứng dụng của bạn được đại diện như một class "mailable". Các class đó được lưu trong thư mục app/Mail. Đừng lo lắng nếu bạn không nhìn thấy đường dẫn đó trong ứng dụng của bạn, vì nó sẽ được tạo ra khi bạn tạo class mailable lần đầu tiên bằng cách dùng lệnh make:mail:

    php artisan make:mail OrderShipped
    

    Writing Mailables

    Tất cả của một class mailable đều được cấu hình trong phương thức build. Bên trong hàm này, bạn có thể gọi nhiều phương thức như from, subject, view, và attach để cấu hình mail nhận.

    Configuring The Sender

    Using The from Method

    Đầu tiên, hãy tìm hiểu cấu hình email của người gửi. Hoặc, theo một nghĩa khác, người gửi mail là "from". Có hai cách để cấu hình người gửi. Đầu tiên, bạn có thể sử dụng phương thức from cùng với phương thức build của class mailable của bạn:

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->from('')
                    ->view('emails.orders.shipped');
    }
    

     

    Using A Global from Address Tuy nhiên, nếu ứng dụng của bạn sử dụng địa chỉ "from" cho tất cả các mail, nó có thể trở lên dài dòng để gọi hàm from trong mỗi class mailable bạn tạo ra. Thay vì, bạn có thể chỉ định địa chỉ "from" trong file cấu hình config/mail.php. Địa chỉ này sẽ được sử dụng nếu không có địa chỉ "from" được chỉ định của class mailable:

    'from' => ['address' => '', 'name' => 'App Name'],
    

     

    Configuring The View Hàm build trong class mailable, bạn có thể sử dụng hàm view để chỉ định template được sử dụng khi render nội dung email. Vì mỗi email sử dụng để render nội dung, bạn có toàn quyền và thoải mái xây dựng Blade templating HTML:

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped');
    }
    

    Plain Text Emails

    Nếu bạn muốn định nghĩa một phiên bản plain-text cho email của bạn, bạn có thể sử dụng hàm text. Giống như hàm view, hàm text nhận một tên template sẽ được sử dụng để render nội dung của email. Nếu bạn định thoải mái nghĩa một HTML và một phiên bản plain-text cho message của bạn:

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped')
                    ->text('emails.orders.shipped_plain');
    }
    

    View Data

    Via Public Properties

    Thông thường, bạn sẽ muốn truyền một số data vào trong view của bạn muốn sử dụng khi render ra HTML. Có hai cách bạn có thể hiển thị dữ liệu trong view. Thứ nhất, bất cứ thuộc tính public được định nghĩa trong class mailable sẽ được tự động tồn tại trong view. Vì vậy, ví dụ, bạn có thể truyền dữ liệu có thuộc tính public vào trong hàm khởi tạo của class mailable và đặt dữ liệu bạn muốn truyền vào trong đó:

    <?php
    
    namespace App\Mail;
    
    use App\Order;
    use Illuminate\Bus\Queueable;
    use Illuminate\Mail\Mailable;
    use Illuminate\Queue\SerializesModels;
    
    class OrderShipped extends Mailable
    {
        use Queueable, SerializesModels;
    
        /**
         * The order instance.
         *
         * @var Order
         */
        public $order;
    
        /**
         * Create a new message instance.
         *
         * @return void
         */
        public function __construct(Order $order)
        {
            $this->order = $order;
        }
    
        /**
         * Build the message.
         *
         * @return $this
         */
        public function build()
        {
            return $this->view('emails.orders.shipped');
        }
    }
    

    Mỗi dữ liệu được set một thuộc tính public, nó sẽ tự động trở thành có sẵn trong view của bạn, vì vậy bạn có thể truy cập nó giống như bạn truy cập bất cứ dữ liệu nào khác trong Blade templates:

    <div>
        Price: {{ $order->price }}
    </div>
    

    Via The with Method:

    Nếu bạn muốn tùy biến định dạng data trước khi gửi nó vào template, bạn có thể tùy biến data của bạn vào view qua phương thức with. Thông thường, bạn sẽ vẫn truyền data qua hàm khởi tạo của class mailable; tuy nhiên, bạn nên đặt data thành thuộc tính protected hoặc privatevì data sẽ không tự động được tạo sẵn trong view template. Sau đó, khi gọi phương thức with, truyền một mảng data bạn muốn vào trong template:

    <?php
    
    namespace App\Mail;
    
    use App\Order;
    use Illuminate\Bus\Queueable;
    use Illuminate\Mail\Mailable;
    use Illuminate\Queue\SerializesModels;
    
    class OrderShipped extends Mailable
    {
        use Queueable, SerializesModels;
    
        /**
         * The order instance.
         *
         * @var Order
         */
        protected $order;
    
        /**
         * Create a new message instance.
         *
         * @return void
         */
        public function __construct(Order $order)
        {
            $this->order = $order;
        }
    
        /**
         * Build the message.
         *
         * @return $this
         */
        public function build()
        {
            return $this->view('emails.orders.shipped')
                        ->with([
                            'orderName' => $this->order->name,
                            'orderPrice' => $this->order->price,
                        ]);
        }
    }
    

    Khi data đã được truyền vào phương thức with, nó sẽ tự động tồn tại ở trong view, bạn có thể truy cập bình thường như khi sử dụng dữ liệu với Blade templates:

    <div>
        Price: {{ $orderPrice }}
    </div>
    

     

    Attachments

    Để đính kèm vào email, sử dụng phương thức attach cùng với phương thức build của class mailable. Phương thức attach chấp nhận đường dẫn đầy đủ của file là tham số thứ nhất:

        /**
         * Build the message.
         *
         * @return $this
         */
        public function build()
        {
            return $this->view('emails.orders.shipped')
                        ->attach('/path/to/file');
        }
    

    Khi đính kèm các file vào một message, bạn cũng có thể ghi rõ display name và / hoặc MIME type bằng cách truyền vào array như là tham số thứ hai của phương thức attach:

        /**
         * Build the message.
         *
         * @return $this
         */
        public function build()
        {
            return $this->view('emails.orders.shipped')
                        ->attach('/path/to/file', [
                            'as' => 'name.pdf',
                            'mime' => 'application/pdf',
                        ]);
        }
    

     

    Raw Data Attachments

    Phương thức attachData có thể sử dụng để đính kèm một raw string của bytes như một đính kèm. Ví dụ, bạn có thể sử dụng phương thức này nếu bạn muốn sinh một PDF trong memory và muốn đính kèm nó vào email mà không cần viết nó vào ổ cứng. Phương thức attachData chấp nhận dữ liệu dạng raw data bytes là tham số thứ nhất, tên của file là tham số thứ hai, và một mảng tùy biến là tham số thứ ba:

        /**
         * Build the message.
         *
         * @return $this
         */
        public function build()
        {
            return $this->view('emails.orders.shipped')
                        ->attachData($this->pdf, 'name.pdf', [
                            'mime' => 'application/pdf',
                        ]);
        }
    

     

    Inline Attachments

    Nhúng inline images vào emails thường không đơn giản; tuy nhiên, Laravel cung cấp một cách khá thuận tiện để bạn đính kèm ảnh vào emails và nhận CID thích hợp. Để nhúng một ảnh inline images, sử dụng phương thức embed trên biến $message cùng với email template. Laravel tự động tạo biến $message tồn tại cho tất cả email templates, vì vậy bạn không cần phải truyền nó một cách thủ công:

    <body>
        Here is an image:
    
        <img src="{{ $message->embed($pathToFile) }}">
    </body>
    

     

    Embedding Raw Data Attachments

    Nếu bạn có một raw data string bạn muốn nhúng vào email template, bạn có thể sử dụng phương thức embedData trên biến $message:

    <body>
        Here is an image from raw data:
    
        <img src="{{ $message->embedData($data, $name) }}">
    </body>
    

     

    Customizing The SwiftMailer Message

    Phương thức withSwiftMessage của class Mailable cho phép bạn đăng ký 1 callback sẽ được gọi với raw SwiftMailer message instance trước khi gửi message. Điều này sẽ cho bạn một cơ hội để tùy chỉnh message trước khi nó được gửi:

        /**
         * Build the message.
         *
         * @return $this
         */
        public function build()
        {
            $this->view('emails.orders.shipped');
    
            $this->withSwiftMessage(function ($message) {
                $message->getHeaders()
                        ->addTextHeader('Custom-Header', 'HeaderValue');
            });
        }
    
    CÓ THỂ BẠN QUAN TÂM

    Bài Viết Cùng Chuyên Mục

    XEM THÊM
    thumbnail

    Kubernetes bài 6 - Vận hành k8s Day-Two Operations và Quản trị bằng GitOps

    22.05.2026

    Khi cụm Kubernetes của bạn đã được bảo mật cấu hình, tối ưu tài nguyên và thiết lập tự phục hồi, câu hỏi đặt ra là làm sao để duy trì sự ổn định đó trong nhiều năm tiếp theo mà không bị phụ thuộc

    thumbnail

    Kubernetes bài 5 - bảo mật Cloud Native và chuẩn DevSecOps cho K8s

    22.05.2026

    Việc siết chặt an ninh (Hardening) không phải là cấu hình một vài thông số rồi bỏ đó, mà là một tư duy phòng thủ chiều sâu.

    thumbnail

    Kubernetes bài 4 - Tối ưu Resource Auto-Healing và Scale Zero-Downtime

    22.05.2026

    Bài viết này sẽ đi sâu vào các cơ chế ở tầng Kernel giúp hệ thống tự phục hồi, chống lại các đợt tấn công cạn kiệt tài nguyên và cập nhật phiên bản mới mà người dùng không hề hay biết.

    thumbnail

    Kubernetes bài 3 - Bảo mật cấu hình k8s và config Security trên Production

    22.05.2026

    Kubernetes giải quyết bài toán này bằng hai đối tượng chuyên biệt nhưng nếu không hiểu rõ bản chất bảo mật ở tầng dưới, bạn đang tự tay dâng toàn bộ chìa khóa hệ thống cho hacker.

    thumbnail

    Kubernetes bài 2 - Mạng lưới k8s và luồng Traffic ở Packet Level

    22.05.2026

    Pod không chỉ là một container: Rất nhiều người nhầm lẫn Pod 1-1 với Container. Thực chất, Pod là đơn vị triển khai nhỏ nhất, có thể chứa một hoặc nhiều container

    Mục lục bài viết