2018-08-23 email view模板无法获取到message 属性的问题

本文探讨了在Laravel框架中使用队列发送邮件的两种不同方式,详细分析了何时实时发送邮件,何时通过队列异步处理。通过具体代码示例,展示了如何配置和使用邮件队列,包括连接数据库、指定队列名称等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   /**
     * email内容。
     */
    public $message;

要将$message设置为public属性。protected是获取不到的。

采用队列发送email,存在模板不能获取到mail类的message数据的问题。我做了2个测试,
第一个测试,用queue推送到默认队列

PhotoNotice.php是mail类

<?php

/*
 * This file is part of PHP CS Fixer.
 * (c) Fabien Potencier <fabien@symfony.com>
 *     Dariusz Rumiński <dariusz.ruminski@gmail.com>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;

class PhotoNotice extends Mailable implements ShouldQueue
{
    use Queueable, SerializesModels;

    /**
     * email内容。
     */
    public $message;

    /**
     * Create a new message instance.
     */
    public function __construct($member)
    {
        $this->message = $member;
    }

    /**
     * Set the recipients of the message.
     *
     * @param  object|array|string  $address
     * @param  string|null  $name
     * @return $this
     */
    public function to($address, $name = null)
    {
        if (config('app.debug')) {
            $temp_testing_email = config('commonsystem_constant.TESTING_EMAIL');
            if (!empty($temp_testing_email)) {
                $testing_email = explode(',', $temp_testing_email);
                return $this->setAddress($testing_email, $name, 'to');
            }
        } else {
            return $this->setAddress($address, $name, 'to');
        }
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->subject('查找圖片通知')->view('emails.photo.notice')->with(['name'=>$this->message->name]);
    }
}

email模板文件

<!DOCTYPE html>
<html lang="{{ config('app.locale') }}">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title></title>
    </head>
    <body>
        <div class="flex-center position-ref full-height">
            <div style='margin-bottom:20px;'>你好:@isset($name) {{$name}} @endisset<br>
                <br>{{config("app.name")}} 系統為你查找到你參與活動的照片,請登入系統查看<br>
               
                <br>
                請點擊以下地址訪問。<br><br>
                <a href="{{config('app.url')}}" target='_blank'>{{config("app.url")}}</a>
                <br>
               
                <div style='width:700px;margin:0;margin-top:20px;color:#8a8a8a;'>
                    <p>此為系統郵件,請勿回覆。</p>
                </div>
                <BR><BR>{{config("app.name")}} 管理員
            </div>
        </div>
    </body>
</html>

第一个测试:

 public function testSendEmail()
    {
        $member_rep = new MemberRepository();
        $member = $member_rep->getById(7);
        $photo_notice = new PhotoNotice($member);
         \Mail::to("davidhuang@nmg.com.hk", 'davidhuang')->queue($photo_notice);
         $this->assertTrue(true);
    }

发现上述email不会加入到jobs表中,并没有经过队列发送,而是实时发送,模板可以获取到name的数据。

第二个测试

 public function testSendEmail()
    {
        $member_rep = new MemberRepository();
        $member = $member_rep->getById(7);
        $photo_notice = (new PhotoNotice($member))
                            ->onConnection('database')
                            ->onQueue('emails');
         \Mail::to("davidhuang@nmg.com.hk", 'davidhuang')->queue($photo_notice);
         $this->assertTrue(true);
    }

第二个测试会将队列加入jobs表中,要经过supervisor执行才会执行,模板无法获取到name。
如果将第二个测试中的 ->onQueue('emails');去掉,也是会加入到db的jobs表中的,也就是说,->onConnection('database')才是真正队列实现的关键。我们来看下mailable的源码

/**
     * Queue the message for sending.
     *
     * @param  \Illuminate\Contracts\Queue\Factory  $queue
     * @return mixed
     */
    public function queue(Queue $queue)
    {
        if (property_exists($this, 'delay')) {
            return $this->later($this->delay, $queue);
        }

        $connection = property_exists($this, 'connection') ? $this->connection : null;

        $queueName = property_exists($this, 'queue') ? $this->queue : null;

        return $queue->connection($connection)->pushOn(
            $queueName ?: null, new SendQueuedMailable($this)
        );
    }

如果没定义$connection,是马上执行的。定义后,就会在db的jobs新增一条job,再手动执行
php artisan queue:work database 则会执行已有的jobs。执行后,收到的email是带有name数据的。

使用supervisor也同样可以执行,name可以获取到。但是需要注意的是,supervisor修改后单单reload或者stop,start是不够的,一定要reread,update,stop,start

sudo supervisorctl reread

sudo supervisorctl update

sudo supervisorctl stop race_photo

sudo supervisorctl start race_photo

2018-08-31 今天又遇到email无法读取message的问题

首先,执行

php artisan cache:clear
php artisan view:clear

还是获取不到。然后我想调试下代码,结果不论是保存到DB还是写入Log都无效,不会生效。搞了很久发现,因为我用了supervisor执行mail的定时任务,修改完代码必须repload supervisor才能生效。mail的message属性可以是数据,collect,eloquent等等。

<?php

/*
 * This file is part of PHP CS Fixer.
 * (c) Fabien Potencier <fabien@symfony.com>
 *     Dariusz Rumiński <dariusz.ruminski@gmail.com>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class PhotoNotice extends Mailable 
{
    use Queueable, SerializesModels;

    /**
     * email内容。
     */
    public $message;

    /**
     * Create a new message instance.
     *
     * @param mixed $member
     */
    public function __construct($name, $url)
    {
        $this->message = collect(['name'=>$name, "url"=>$url]);
    }

    /**
     * Set the recipients of the message.
     *
     * @param object|array|string $address
     * @param string|null         $name
     *
     * @return $this
     */
    public function to($address, $name = null)
    {
        if (config('app.debug')) {
            $temp_testing_email = config('commonsystem_constant.TESTING_EMAIL');
            if (!empty($temp_testing_email)) {
                $testing_email = explode(',', $temp_testing_email);

                return $this->setAddress($testing_email, $name, 'to');
            }
        } else {
            return $this->setAddress($address, $name, 'to');
        }
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->subject('查找圖片通知')->view('emails.photo.notice')->with(['name'=>$this->message->get("name"), 
                                                                           'url'=>$this->message->get("url")]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值