Прослушиватель событий Уведомлений Laravel Неопределенное свойство
У меня следующая ошибка:
Неопределенное свойство: Осветить\Уведомления\События\Отправку уведомлений::$пользователь в /var/www/приложение/приложение/Слушатели/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 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
привязан к модели User
, но если он срабатывает правильно для всех затронутых пользователей из приложения, почему его свойство должно быть undefined
в этот контекст?
Пожалуйста, помогите, спасибо.
1 answers
Это странная проблема. Как вы обнаружили, Laravel не устанавливает свойство $user
для самого этого объекта, поэтому должно быть задействовано что-то еще. Вот мое понимание этого процесса:
-
Notification::send()
→ поставить в очередьNewAsset
уведомление для каждого пользователя - Удаление из очереди внутреннего задания для
NewAsset
уведомления → отправка уведомлений - Пожар
NotificationSent
событие → постановка в очередьNotificationListener
обработчик
Похоже, здесь произошла ошибка:
- Удаление из очереди внутреннего задания для
NotificationListener
обработчика → события обработки - Задание отправки для
SendEmail
[→поставить в очередь, еслиShouldQueue
] - [Удалить задание из очереди для
SendEmail
, еслиShouldQueue
→] Отправить уведомление по электронной почте
Как вы можете видеть, при постановке в очередь и удалении заданий для уведомление. Похоже, что фреймворк пытается установить свойство $user
при десериализации события NotificationSent
из очереди, но по вашему вопросу трудно судить без полной трассировки стека, и я не уверен, что добавляет $user
к сериализованным данным без большей видимости в коде.
Вот несколько предложений по отладке, которые можно попробовать:
Перезапустите работника очереди:
После запуска работника очереди PHP процесс не загружает изменения в исходный код с диска, если загрузчик уже импортировал файл. Кажется возможным, что кто-то добавил свойство $user
к объекту, но не перезапустил работника, поэтому он так и не принял изменения. Во время разработки нам необходимо перезапускать работников очереди всякий раз, когда изменяется код для элемента, подлежащего очереди. При развертывании в рабочей среде рекомендуется перезапустить работников очереди как часть процесса развертывания.
В качестве альтернативы используйте artisan queue:listen
команда вместо queue:work
во время разработки. Этот режим перезапускает всю платформу для каждого задания.
Установите QUEUE_DRIVER
в sync
:
Это предотвращает сериализацию данных событий в системе событий фреймворка. Если уведомление по электронной почте отправляется без каких-либо ошибок, то мы знаем, что где-то пользовательский код добавляет свойство $user
к событию.
Проверка сериализованной очереди данные:
Из вопроса неясно, какой драйвер очереди использует ваше приложение. Если вы не используете sync
, Мы можем просмотреть отложенные задания в очереди, чтобы попытаться найти несоответствие (в базе данных, Redis и т. Д.).
- Остановите всех работников очереди.
- Запустите уведомление через приложение.
- Запустите
php artisan queue:work --once
, чтобы вручную обработать одно задание, пока задание в очереди не запустится и не вызовет событиеNotificationSent
. - Проверьте задание, созданное в очереди, чтобы обработать событие
NotificationSent
Мы также можем использовать этот подход для сброса данных с помощью dd()
во время заданий очереди, потому что artisan queue:work --once
выполняется на переднем плане.
Не ставьте в очередь обработчик событий NotificationSent
:
Поскольку уведомление уже настроено для обработки в фоновое задание в очереди, нам не обязательно также ставить в очередь обработчик событий уведомлений. Попробуйте удалить интерфейс ShouldQueue
, чтобы посмотреть, решит ли это проблему.
Как упоминали другие комментаторы, эта проблема может быть лучше решена с помощью почтовых уведомлений Laravel , которые полностью устраняют необходимость в отдельном обработчике событий NotificationSent
.