我有以下错误:
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_DRIVER
至 sync
:这可以防止框架的事件系统序列化事件数据。如果通知电子邮件发送没有任何错误,那么我们知道某处的自定义代码正在添加
$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/