php - Laravel 通知事件监听器未定义的属性

标签 php laravel laravel-5 laravel-5.3

我有以下错误:

Undefined property: Illuminate\Notifications\Events\NotificationSent::$user in /var/www/app/app/Listeners/NoticationListener.php:31



错误发生在这里:
<?php

namespace App\Listeners;

use Illuminate\Notifications\Events\NotificationSent;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

class NoticationListener implements ShouldQueue
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  NotificationSent  $event
     * @return void
     */
    public function handle(NotificationSent $event)
    {
       $notification = $event->notifiable;
       $addressee = $notification; //error here
       $address = $notification; 
       $type = "Notification";
       dispatch(new SendEmail($type,$addressee,$address));
    }
}

我不明白这个未定义的属性,尤其是在这一行。我该怎么办 dd()从这里?我试图登录 $event但我无法让它记录,只有这个错误。

我的通知在应用程序中工作得很好,我只想要一封电子邮件陪伴他们,这就是为什么我有这个事件监听器/工作。

谢谢你。

编辑

发送通知的存储库代码如下:
public function notify($asset)
{
    $users = User::where("id","!=",Auth::user()->id)->get();
    Notification::send($users, new NewAsset($asset));
}
Notification的那个扩展类(class)如下:
class NewAsset extends Notification
{
    use Queueable;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    protected $asset;

    public function __construct($asset)
    {
        $this->asset = $asset;
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['database'];
    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            'asset_id' => $this->asset->id
        ];
    }
}

编辑 2

如果有人可以建议如何在此时进行一些错误检查,那可能会有所帮助。因为代码在服务器上是异步的,所以它不会将数据返回给客户端,当我尝试将其发送到 Log 时在陷入错误之前,它似乎并没有这样做。

在这种情况下如何进行调试?

我看过框架的 source code并且不知道 $user 属性来自哪里。我认为它与 $event->notifiable 有关被绑在 User模型,但如果它为应用程序中所有受影响的用户正确触发,为什么它的属性是 undefined在这种情况下?

请帮忙,谢谢。

最佳答案

这是一个奇怪的问题。正如你发现的那样,Laravel 没有设置 $user该对象本身的属性,因此必须涉及其他内容。以下是我对这个过程的理解:

  • Notification::send() → 入队 NewAsset每个用户的通知
  • 出列 NewAsset 的内部作业通知 → 发送通知
  • NotificationSent事件 → 入队 NotificationListener处理程序

  • 错误似乎发生在这里:
  • 出列 NotificationListener 的内部作业处理程序 → 处理事件
  • SendEmail的 dispatch 工作[→ 入队如果 ShouldQueue ]
  • [出队作业 SendEmail如果 ShouldQueue →] 发送通知邮件

  • 如您所见,在为通知将作业入队和出队时,会进行大量序列化和反序列化。该框架似乎正在尝试设置 $user反序列化 NotificationSent 时的属性队列中的事件,但是如果没有完整的堆栈跟踪,很难从您的问题中判断出来,而且我不确定是什么添加了 $user序列化数据,而无需更多地了解代码。

    以下是一些可以尝试的调试建议:

    重启队列 worker :

    队列 worker 启动后,如果自动加载器已导入文件,PHP 进程不会从磁盘重新加载对源代码的更改。似乎有人添加了 $user属性到一个对象,但没有重新启动工作程序,所以它从来没有拿起变化。在开发过程中,每当可排队项目的代码发生更改时,我们都需要重新启动队列工作器。部署到生产环境时,最好在部署过程中重新启动队列工作器。

    或者,使用 artisan queue:listen命令而不是 queue:work在开发过程中。此模式为每个作业重新启动整个框架。

    套装QUEUE_DRIVERsync :

    这可以防止框架的事件系统序列化事件数据。如果通知电子邮件发送没有任何错误,那么我们知道某处的自定义代码正在添加 $user事件的属性(property)。

    检查序列化队列数据:

    从您的应用程序使用哪个队列驱动程序的问题中不清楚。如果您不使用 sync ,我们可以查看队列中的待处理作业以尝试找出差异(在数据库、Redis 等中)。
  • 停止所有队列工作器。
  • 通过应用程序触发通知。
  • 运行 php artisan queue:work --once手动处理一项作业,直到排队的作业运行并触发 NotificationSent事件。
  • 检查队列中创建的作业以处理 NotificationSent事件

  • 我们也可以使用这种方法使用 dd() 转储数据。在队列作业期间,因为 artisan queue:work --once在前台运行。

    不要排队 NotificationSent事件处理程序 :

    由于通知已配置为在排队的后台作业中处理,因此我们不一定也需要将通知事件处理程序加入队列。尝试删除 ShouldQueue界面,看看这是否解决了问题。

    正如其他评论者所提到的,使用 Laravel 的 Mail Notifications 可能会更好地解决这个问题。不需要单独的 NotificationSent事件处理程序完全。

    关于php - Laravel 通知事件监听器未定义的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46258880/

    相关文章:

    php - 为什么我在 Laravel View 中得到 "Undefined variable"?

    php - 获取 laravel 5 中所有 Controller 和 Action 的列表

    php - 缓存错误类不存在 - Laravel 5.7

    mysql - 从具有列外键的表中查询

    Laravel API 资源集合从其他资源返回特定字段

    php - MySQL SUM 不返回正确的值,它会删除小数位。如何防止这种情况?

    php - 带有密码和 PHP 的 Solr http 请求 api

    php - 读取 url 内容,无缓冲的 php

    android - ios/android 应用的 Laravel 密码加密/解密机制

    php - 为什么要使用多个 PHP Exception 类