Php Laravel通知事件侦听器未定义属性

Php Laravel通知事件侦听器未定义属性,php,laravel,laravel-5,laravel-5.3,Php,Laravel,Laravel 5,Laravel 5.3,我有以下错误: 未定义的属性: 照亮\Notifications\Events\NotificationSent::$user in /var/www/app/app/Listeners/notationlistener.php:31 错误发生在以下位置: <?php namespace App\Listeners; use Illuminate\Notifications\Events\NotificationSent; use Illuminate\Queue\InteractsW

我有以下错误:

未定义的属性: 照亮\Notifications\Events\NotificationSent::$user in /var/www/app/app/Listeners/notationlistener.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));
    }
}
通知类的扩展如下所示:

public function notify($asset)
{
    $users = User::where("id","!=",Auth::user()->id)->get();
    Notification::send($users, new NewAsset($asset));
}
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
时,它似乎在被错误捕获之前不会这样做

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

我已经看过了框架,不知道$user属性来自哪里。我假设它与
$event->notifiable
绑定到
用户
模型有关,但是如果它从应用程序中为所有受影响的用户正确触发,为什么在这种情况下它的属性是
未定义的


请协助,谢谢。

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

  • Notification::send()
    → 为每个用户排队
    NewAsset
    通知
  • NewAsset
    通知退出内部作业队列→ 发送通知
  • 火灾
    通知已发送
    事件→ 排队
    NotificationListener
    处理程序
  • 此处似乎发生了错误:

  • NotificationListener
    处理程序的内部作业出列→ 处理事件
  • sendmail
    [→ 如果
    应排队,则排队
  • [如果
    ShouldQueue
    →] 发送通知电子邮件
  • 如您所见,在将作业排入队列或从队列中退出时,会进行大量序列化和反序列化。在从队列中反序列化
    NotificationSent
    事件时,框架似乎试图设置
    $user
    属性,但很难从您的问题中分辨出来没有完整的堆栈跟踪,我不确定是什么在没有更多代码可见性的情况下向序列化数据添加了
    $user

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

    重新启动队列工作程序:

    队列工作程序启动后,如果自动加载程序已导入文件,则PHP进程不会从磁盘重新加载对源代码的更改。可能有人向对象添加了
    $user
    属性,但没有重新启动工作程序,因此它从未接收到更改。在开发过程中,我们需要重新启动队列工作程序每当可排队项的代码发生更改时。部署到生产环境时,最好在部署过程中重新启动队列工作程序

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

    QUEUE\u驱动程序设置为
    sync

    这会阻止框架的事件系统序列化事件数据。如果通知电子邮件发送时没有任何错误,则我们知道某个地方的自定义代码正在向事件添加
    $user
    属性

    检查序列化队列数据:

    您的应用程序使用哪个队列驱动程序还不清楚。如果您没有使用
    sync
    ,我们可以查看队列中的挂起作业,以尝试查找差异(在数据库、Redis等中)

  • 停止所有排队的工作人员
  • 通过应用程序触发通知
  • 运行
    php artisan queue:work--one
    手动处理一个作业,直到排队作业运行并触发
    NotificationSent
    事件
  • 检查队列中创建的作业,以处理
    NotificationSent
    事件
  • 我们还可以使用这种方法在队列作业期间使用
    dd()
    转储数据,因为
    artisan queue:work--once
    在前台运行

    不要将
    NotificationSent
    事件处理程序排入队列

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


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

    您能向我们展示您的NotificationSent事件吗?@EduardoPacios这是框架代码-请参见此处()如果在用户抛出异常时未使用Notifiable trait,那么我也会运行此通知类,如下所示:BadMethodCallException:调用未定义的方法Illumb\Database\Query\Builder::routeNotificationFor(),但您的错误一定很严重,请将queue on sync和测试值设置为$Event,您可以在所有通知类和实现方法toMail()上通过邮件使用;在每个通知上,您可以使用另一个发送邮件的实现、一些视图、文本和…,以便使用
    dd()调试您的队列
    您需要在
    .env
    =>queue\u DRI中将队列驱动程序设置为同步