Как обрабатываются в Laravel события создание класса event и вызов функции fire


Содержание материала:

Laravel — Events

Вступление

События Laravel предоставляют простую реализацию наблюдателя, позволяющую вам подписываться и прослушивать различные события, которые происходят в вашем приложении. Классы событий обычно хранятся в каталоге, а их слушатели — в . Не беспокойтесь, если вы не увидите эти каталоги в своем приложении, поскольку они будут созданы для вас, когда вы генерируете события и прослушиватели с помощью консольных команд Artisan. app/Events app/Listeners

События служат отличным способом разъединить различные аспекты вашего приложения, поскольку одно событие может иметь несколько слушателей, которые не зависят друг от друга. Например, вы можете отправлять уведомления Slack своему пользователю каждый раз, когда заказ отправлен. Вместо того, чтобы связывать код обработки заказа с кодом уведомления Slack, вы можете вызвать OrderShipped событие, которое слушатель может получить и преобразовать в уведомление Slack.

Регистрация событий и слушателей

EventServiceProvider В комплекте с приложением Laravel обеспечивает удобное место для регистрации всех слушателей событий вашего приложения. listen Свойство содержит массив всех событий (ключи) и их слушателей (значения). Вы можете добавить столько событий в этот массив, сколько требует ваше приложение. Например, давайте добавим OrderShipped событие:

Генерация событий и слушателей

Конечно, создание файлов для каждого события и слушателя вручную затруднительно. Вместо этого добавьте слушателей и события к себе EventServiceProvider и используйте команду. Эта команда будет генерировать любые события или прослушиватели, которые перечислены в вашем . События и слушатели, которые уже существуют, останутся нетронутыми: event:generate EventServiceProvider

Регистрация событий вручную

Как правило, события должны быть зарегистрированы через EventServiceProvider $listen массив; однако вы также можете зарегистрировать события, основанные на замыкании, вручную, используя boot метод EventServiceProvider :

Слушатели событий с подстановочными знаками

Вы даже можете зарегистрировать слушателей, используя * параметр подстановки, позволяющий перехватывать несколько событий на одном и том же слушателе. Слушатели подстановочных знаков получают имя события в качестве первого аргумента и весь массив данных события в качестве второго аргумента:

Обнаружение событий

Обнаружение событий доступно для Laravel 5.8.9 или новее.

Вместо регистрации событий и прослушивателей вручную в $listen массиве EventServiceProvider , вы можете включить автоматическое обнаружение событий. Когда обнаружение событий включено, Laravel автоматически найдет и зарегистрирует ваши события и слушателей, отсканировав Listeners каталог вашего приложения . Кроме того, любые явно определенные события, перечисленные в, EventServiceProvider все равно будут зарегистрированы.

Laravel находит прослушиватели событий путем сканирования классов слушателей с использованием отражения. Когда Laravel находит какой-либо метод класса слушателя, который начинается с handle , Laravel зарегистрирует эти методы в качестве слушателей события для события, на которое указывается тип в сигнатуре метода:

По умолчанию обнаружение событий отключено, но вы можете включить его, переопределив shouldDiscoverEvents метод вашего приложения EventServiceProvider :

По умолчанию все прослушиватели в каталоге Listeners вашего приложения будут сканироваться. Если вы хотите определить дополнительные каталоги для сканирования, вы можете переопределить discoverEventsWithin метод в вашем EventServiceProvider :

В производственной среде вы, вероятно, не хотите, чтобы инфраструктура сканировала всех ваших слушателей при каждом запросе. Поэтому в процессе развертывания вы должны выполнить команду Artisan, чтобы кэшировать манифест всех событий и прослушивателей вашего приложения. Этот манифест будет использоваться платформой для ускорения процесса регистрации событий. Команда может быть использована для уничтожения кэша. event:cache event:clear

Команда может быть использована для отображения списка всех событий и слушателей , зарегистрированных приложением. event:list

Определение событий

Класс события — это контейнер данных, который содержит информацию, связанную с событием. Например, предположим, что наше сгенерированное OrderShipped событие получает объект Eloquent ORM :

Как видите, этот класс событий не содержит логики. Это контейнер для Order экземпляра, который был куплен. SerializesModels Черта используется событие будет корректно сериализовать любые красноречивые модели , если объект события сериализации с помощью РНР serialize функции.

Определение слушателей

Далее, давайте посмотрим на слушателя нашего примера события. Слушатели событий получают экземпляр события в своем handle методе. Команда автоматически импортирует соответствующий класс событий и напечатает подсказку о событии в методе. В рамках метода вы можете выполнить любые действия, необходимые для ответа на событие: event:generate handle handle

Ваши слушатели событий могут также указывать любые зависимости, которые им нужны от их конструкторов. Все прослушиватели событий разрешаются через служебный контейнер Laravel , поэтому зависимости будут вставлены автоматически.

Остановка распространения события

Иногда вы можете остановить распространение события на других слушателей. Вы можете сделать это, вернувшись false из handle метода вашего слушателя .

Прослушиватели событий в очереди

Слушатели в очереди могут быть полезны, если ваш слушатель будет выполнять медленную задачу, такую ​​как отправка электронной почты или отправка HTTP-запроса. Прежде чем начать работу с прослушивателями в очереди, обязательно настройте свою очередь и запустите прослушиватель очереди на своем сервере или в локальной среде разработки.

Чтобы указать, что слушатель должен быть поставлен в очередь, добавьте ShouldQueue интерфейс в класс слушателя. Слушатели, сгенерированные командой Artisan, уже импортировали этот интерфейс в текущее пространство имен, поэтому вы можете использовать его немедленно: event:generate

Это оно! Теперь, когда этот прослушиватель вызывается для события, он автоматически будет поставлен в очередь диспетчером событий с использованием системы очередей Laravel . Если никакие исключения не генерируются, когда слушатель выполняется в очереди, заданное в очереди задание будет автоматически удалено после завершения обработки.

Настройка подключения к очереди и имени очереди

Если вы хотите , чтобы настроить подключение очереди, имя очереди, или в очереди время задержки прослушивателя событий, вы можете определить $connection , $queue или $delay свойства на классе слушателя:

Доступ к очереди вручную

Если вам нужно вручную получить доступ к заданию delete и release методам очереди слушателя , вы можете сделать это, используя эту черту. Эта черта импортируется по умолчанию для сгенерированных слушателей и предоставляет доступ к этим методам: Illuminate\Queue\InteractsWithQueue

Обработка неудачных заданий

Иногда ваши слушатели событий в очереди могут потерпеть неудачу. Если прослушиватель в очереди превышает максимальное количество попыток, как определено вашим работником очереди, failed метод будет вызван на вашем слушателе. failed Метод получает экземпляр события и исключение , которое вызвало отказ:

Диспетчерские события

Для отправки события вы можете передать экземпляр события event помощнику. Помощник отправит событие всем зарегистрированным слушателям. Поскольку event помощник доступен по всему миру, вы можете вызывать его из любого места в вашем приложении:

При тестировании может быть полезно утверждать, что определенные события были отправлены без фактического запуска их слушателей. Встроенные в Laravel помощники по тестированию делают это проще простого.

Подписчики событий

Написание событий подписчиков

Подписчики событий — это классы, которые могут подписываться на несколько событий внутри самого класса, что позволяет вам определять несколько обработчиков событий в одном классе. Подписчики должны определить subscribe метод, которому будет передан экземпляр диспетчера событий. Вы можете вызвать listen метод данного диспетчера для регистрации прослушивателей событий:

Регистрация подписчиков на события

После написания подписчика вы готовы зарегистрировать его у диспетчера событий. Вы можете зарегистрировать подписчиков, используя $subscribe собственность на EventServiceProvider . Например, давайте добавим UserEventSubscriber в список:

обработка событий входа в laravel 5

Я пытаюсь подключиться к логину даже в моем приложении L5, чтобы установить последнее время входа и IP-адрес. я могу заставить его работать со следующим:

однако мне интересно, как лучше всего это сделать в L5 с объектом обработчика событий. я попытался создать обработчик событий и добавить auth.войдите в систему как ключ массива в поставщике услуг событий, однако это не сработало. я не уверен, что это возможно или нет с auth.событие входа в систему. если это не так, где наиболее подходящих место для размещения вышеуказанного кода. для тестирования я включил его в свои маршруты.php-файл, но я знаю, что он не там, где должен быть.

6 ответов

в laravel 5.2; auth.логин не будет работать. необходимо будет использовать следующее:

как указано в документации здесь

EDIT: это работает только в 5.0.* и 5.1.*.

для 5.2.* решение см. ответ JuLiAnc ниже.

после работы с обоими предложенными ответами и еще некоторыми исследованиями я, наконец, понял, как это сделать так, как я пытался сначала.

Я выполнил следующую команду ремесленника

затем я изменил созданный класс, удалив импорт класса событий и импортировал модель пользователя. Я также прошло User $user и $remember к методу дескриптора с тех пор, когда auth.событие login запускается, вот что передается.

теперь я открыл EventServiceProvided.php и изменил $listen массив следующим образом:

я понял, что если это не сработает, во-первых, вам может понадобиться

здесь мы идем! теперь мы можем ответить на вход пользователя через auth.войти событие, используя класс обработчика событий!

будьте осторожны, спрашивая о что лучший способ сделать X

посмотреть документация Laravel, лично я бы пошел с «основным использованием», как кажется, в соответствии с прецедентом, который вы указали.

если мы запустим следующую команду Artisan, мы можем создать шаблон для Событие UserLoggedIn.

(обратите внимание на прошедшее время, потому что события происходят, и затем абоненты уведомляются о произошедшем событии)

(примечание 2: app строка в пространствах имен-это то, что Laravel использует из коробки, это, вероятно, отличается для вас, если вы выполнили )

для нас генерируется следующий класс:

если мы добавляем userId параметр конструктора, тогда событие не должно знать о контракте auth Facade/Guard. Это значит наш UserLoggedIn код события не тесно связан с красноречивым или который когда-либо рамки аутентификации вы решили использовать в своем приложении. В любом случае, давайте добавим, что .

теперь вам, наверное, интересно, Ну это, конечно, замечательно, но как мы будем действовать на этом случае? Отличный вопрос! Нам нужно создать обработчик событий для обработки при запуске этого события. Давайте сделаем это сейчас, используя Ремесленник:

мы называем наш новый обработчик событий UpdateUserMetaData и скажите ремесленнику, что событие, которое мы хотим обработать, это UserLoggedIn событие.

теперь у нас есть код, который выглядит так внутри app/Handlers/Events/UpdateUserMetaData.php :

мы можем обновить метод дескриптора, чтобы иметь возможность обрабатывать это событие, как вы указали выше, довольно легко:

есть два последних шага, которые мы должны выполнить, прежде чем этот код будет работать в вашем приложении Laravel.

нам нужно сопоставить событие с обработчиком событий в EventServiceProvider класс под .

нам нужно запустить событие после входа в систему.


чтобы завершить первый шаг, нам нужно добавить наши классы событий к $listeners в собственность app/Providers/EventServiceProvder.php вот так:

выше будет работать при условии, что вы импортировать классы внутри EventServiceProvider класс, и вы используете PHP 5.5. Если вы используете более низкую версию PHP, вам потребуется указать полный путь к каждому классу как строка, как это: ‘app/Events/UserLoggedIn’ и ‘app/Handlers/Events/UpdateUserMetaData’ .

на $listeners массив сопоставляет события соответствующим обработчикам.

хорошо, теперь последний шаг! В базе кода найдите место, где пользователь проходит проверку подлинности, и добавьте следующее:

и мы сделали это! Я тестировал этот код, когда писал этот ответ, не стесняйтесь задавать последующие вопросы, если у вас есть.

Как правильно подгрузить свои классы и функции в laravel ?

Например у нас есть controller в котором методы для страницы регистрации, авторизации личного кабинета. Есть класс модели User управляющий таблицей users на основе active record
Допустим я хочу подключить класс UserAccount для внутреннего счета который не будет laravel’ой моделью, то есть не будет наследоватся как extends Model а чисто мой интерфейс.. может вообще голые функции без класса захочу подключить, хотя и вряд ли. И хочу вызывать эти классы/функции в controller?

Как это верно сделать? Аналогом require_once или как то еще? Хочется как проще.

23.03.2020, 22:01

Как правильно архивировать laravel 5.5 приложение?
Всем привет,* Подскажите как правильно архивировать laravel 5.5 приложение — если архивировать.

Как правильно сделать структуру в Laravel не нарушая MVC?
Добрый день.Первый раз работаю с Laravel,читаю много информации в Интернете, и меня смущает,то в.

Как правильно биндить свои классы к TreeView
Привет всем 🙂 Я не могу понять, как правильно биндить свои классы к TreeView. вот так у меня.

Как правильно обновлять свои OCX
При добавлении в свою OCX MyOcx.ocx новых контролов при последующей попытке подцепить ее через.

Как правильно перелинковать свои сайты?
Как лучше перелинковать десяток своих сайтов разной тематики? 1. Сделать ссылки со всех сайтов на.

24.03.2020, 14:16 2 24.03.2020, 21:12 [ТС] 3

Сделал как то так

И затем подключаю

25.03.2020, 08:47 4
25.03.2020, 08:47
26.03.2020, 00:03 [ТС] 5

В общем решил попробовать все таки использовать laravel модели для таблиц и orm, в сочетании с db raw где по другому не получается.

Но тут возник такой вопрос.

Допустим в контроллере, мне нужно скажем принять платеж от юзера, оформить ему подписку.
Да я использую для этого объекты моделей laravel например так:

Но пусть я хочу все это спрятать в какой то метод. Ну скажем payFromUserBalance() куда такой метод правильно было бы запихнуть, в какой то из классов который наследует от Model и моделирует таблицу. Ну например в Users или Trans. Или лучше создавать для таких нужд отдельные классы без наследования от Model Что то вроде:

26.03.2020, 21:16 6
27.03.2020, 19:45 [ТС] 7
06.05.2020, 13:49 [ТС] 8

На данный момент функционал связанный с данным кодом отлажен вместе с тестовым платежным шлюзом. Временно переключились на другой проект.

До Repository только сейчас начинаю читать разбираться.. Переписывать возможно и не буду, но думаю как бы было с ним..

Как я понимаю Repository обертывает запросы sql или orm для данной или связанной с ней таблиц, например в моем случае вместо:

То есть для users был бы репозиторий, который бы содержал методы где запросы к users или связанным таблицам, ну где нужен user_id, в него бы я запихнул все эти orm запросы.
Ну а в целом слой бизнес логики который определяет алгоритм типа:
Смотрим баланс
Вычитаем сумму
Если нельзя отрицательный баланс выдаем ошибку
Добавляем в транзакции и обновляем баланс

Все равно должен быть не в репозитории, а в отдельном классе, который просто подключается к контроллеру, ну или просто в методе контроллера если не заморачиваться.

Пишем приложения на Laravel, которые легко поддерживать.

Это расшифровка моего доклада с Laracon AU.

Создание BaseCode и Shift дало мне уникальное понимание написания приложений на Laravel. Я объединил свои 20 лет программирования и 20 000 апгрейдов Ларавел в 10 советов по созданию легко обслуживаемых приложений.

Они могут показаться вам фундаментальными и не обязательными. Но любой серьезный код на Laravel использует их. Проще говоря, чем больше советов вы используете, тем более понятным будет ваша код.

Иди в ногу со временем

Начнем с самого главного — будь актуальным. Да, вы слышите это от создателя Shift. Но тем не менее это так.

Слишком много приложений, по разными причинам, решили остаться устаревшими. Я обязан вам сказать, что LTS (Долгосрочная поддержка) — это ловушка, форки фреймворка — наивно, а изменения в папке vendor — отложенная катастрофа.

Некоторым эти действия могут показаться глупыми, но раз приложение уже устарело, то многие выбирают подобные способы обновления. Это билет в один конец, к коду, который невозможно обслуживать.

Сохранение актуальности позволяет воспользоваться всеми новейшими функциями и сервисами, а также помогает сообществу расти и развиваться. Так что вам не обязательно быть на передовой, но вы должны хотеть быть в авангарде.

Принимай стандарты

Сейчас я хочу обратить ваше внимание на стандарты оформления кода. Вы можете не соглашаться со всеми стандартами. Мне, например мне не нравится пробел в ! (оператор отрицания). Или нехватка пробелов для . (оператор конкатенации). Но, когда я пишу на Laravel, я стараюсь им следовать.

Тем не менее, многие разработчики создают свои собственные стандарты. По факту, я все еще получаю тикеты, о том, что Shift непригоден для использования, так как он переформатировал их код. Я знаю, что стиль кода, это как стиль одежды — личная, идентификационная черта.

В конце концов, это нормально, если вы хотите настроить его под себя и автоматизировать. В идеале используя PHP CS Fixer. Shift использует файл .php_cs в вашем проекте для форматировании кода.

Тщеславные пространства имен

Никогда не меняйте пространство имен App . Тейлор и Джеффри Уэй уже отказались ото подобного. Даже artisan-команда app:name была удалена. Несмотря на все это, я все еще вижу проекты, делающие это.

Меняя его, вы вынуждены следить за ним в нескольких местах. Что увеличивает накладные расходы на техническое обслуживание и создает барьер для входа в проект. Рассмотрим файл HTTP/Kernel . Он содержит 23 ссылки на пространство имен App . Это 23 дополнительные точки, которые нужно будет обслуживать.

Я понимаю, что можно просто сделать поиск и замену, но все это добавляет лишние движения к обычным действиям разработчика, таким, например, как копипаста кода из StackOverflow, Laracasts или документации.

Независимо от настройки пространства имен, я всегда рекомендую использовать morphMap для любых полиморфных или динамических связей модели, сохраненных в базе данных. Это отделит ваш код от БД.

Дефолтная структура

Подобно поддержке стандартов, я рекомендую вам максимально придерживаться дефолтной структуре папок Laravel. Я вижу приложения, создающие свои собственные структуры в папке app. Часто для модульности или разделения кода по доменам.

Тем не менее, в этих папках все равно воссоздаются дефолтные структуры. Controllers, Models, Events. Это создает еще большие накладные расходы, что, в конечном итоге, начинает конкурировать с дефолтной структурой. Это приводит к параллельным иерархиям наследования, что является сигналом Кода с душком.

Вместо этого вы можете свернуть их в дефолтную структуру. При необходимости вы можете организовать домены внутри основных папок.Я знаю, что отделение кода домена от кода приложения поначалу кажется хорошей идеей, но разработчики, выбравшие этот путь, в конце концов жалеют об этом. Помните, что код приложения — это код вашего домена, поэтому его не нужно нигде хоронить.

К чему все приведет

Еще один распространенный вопрос, связанный со структурой, к чему все это приведет?

Опять таки, Laravel в своей изначальной структуре предоставляет множество папок на выбор. Я полагаю, что большинство классов могут быть организованы в одной из них. А если это не подходит, то размещайте его в папке Services .

В этой папке будут находиться классы, которые самоорганизуются со временем. Как только они достигнут критической массы, реструктурируйте их в свою собственную папку верхнего уровня, например: Facades, Clients, Contracts, Traits и т.д.

Это может показаться способом для ленивых, но это поможет избежать неправильной абстракции. Я обсуждаю этого в Правиле Трёх из BaseCode. Предпосылка будущего — ты всегда умнее, чем ты сейчас. Поэтому, если вы сможете сейчас отложить принятие решения, то потом найдете лучшую абстракцию.

Управление пакетами

Composer позволяет очень просто использовать пакеты и управлять ими. До такой степени, что мы даже не задумываемся об их поддержке. Но, любой пакет, который мы вносим в наше приложение, является кодом, которым мы должны управлять. Код, с которым связан код нашего приложения.

Это то, что мы должны помнить перед добавлением пакета. Всегда проверяйте, что ваши пакеты правильно зарегистрированы. Метрики от Shift показывают, что многие приложения неправильно требуют зависимости в режиме development. То есть код, который не «требуется» на продакшне. Например, пакет barryvdh/laravel-debugbar.

Многие простые пакеты раздуты и быстро устаревают или забрасываются своими авторами. Вспомним некогда популярный пакет laracasts/Commander. Сейчас он давно заброшен и заменен кодом в ядре.

Тем не менее, мы все еще можем использовать этот пакет в качестве примера. Он содержит 7 файлов для выполнения одной простой вещи — выполнения обработчика команды. Весь этот код может быть одним трейтом с одним методом execute . Сделайте так и не нужно будет заботится об этом пакете вообще.

Конечно, нет необходимости так поступать с каждым пакетом. Но простой функционал может быть ассимилирован в ваш проект для удобства дальнейшего сопровождения.

Плавные биндинги

Laravel обеспечивает много динамики, что может привести к путанице относительно того, что и где находится. А биндинги самые большие путаники.

Для борьбы с этим зарегистрируйте их в одном месте. В идеале в AppServiceProvider . По возможности используйте свойства $bindings и $singletons , чтобы их было легко идентифицировать.

В Ларавеле есть и другие бинлдинги, которым может быть полезна данная практика, например: Events, Policies, Commands, Broadcasts и Routes.

Расписывая свои маршруты, помните, что есть как API, так и веб-маршруты. Слишком часто я вижу, что все подряд размещается в веб-маршрутах, даже если это маршурт API.

Существует огромная разница в мидлваре, используемом для этих двух типов маршрутов. Например, конечная точка API использует мидлвар, загружающий сессию и куки. Это может привести не только к вредным привычкам при создании конечных точек, но и к несовместимости в будущем, если эти мидлвары изменятся.

Конфигурирование Конфигов


Это правда — файлы конфигурации можно настраивать и обновлять. Также верно, что эти файлы являются наиболее часто изменяемыми в Ларавел. Есть удобные способы управления ими и поддержки. Я уже рассказывал об этом в моей предыдущей статье «Ведение конфигурационных файлов в Ларавел».

Избегайте переопределения

Подобно форматированию и структуре, многие приложения вводят собственные абстракции для основных компонентов. Например, создают что-то вроде BaseModel. Эта BaseModel задает некую общую логику, например, незащищенные атрибуты, или иногда, полностью переопределяет основные методы, чтобы немного изменить их работу.

Но это отделяет вас от фреймворка. А это плохо. Возникают все те же проблемы, как если бы вы форкнули сам Ларавел. Вы больше не получите функций и изменений, которые Ларавел внесет в эти переопределенные методы.

Вместо внедрения слоя наследования рассмотрите возможность использования трейтов. В данном случае Unguarded трейта. Я расскажу об этом подробнее в следующем совете. А пока давайте посмотрим на другой пример, касающийся переопределения основных методов.

Я часто вижу, как разработчики переопределяют основные методы аутентификации. Опять же, делать это по простым причинам, например настройка ответа. Если вы посмотрите на код, Laravel предоставляет способы сделать это, не переопределяя весь метод, что позволяет нам делать это аккуратно.

Например, мы можем просто переопределить аутентификационный метод. В нем мы можем использовать дополнительную логику или перенаправить пользователя.

Laravel предоставляет все виды методов и свойств обратных вызовов. Например, Form Request имеет свойство для изменения редиректа. Вы можете добавить методы render или report к кастомным исключениям, для лучшей обработки ошибок.

Вы можете подключиться к основной функциональности через события. Laravel запускает события для всех видов основного поведения. Вы можете зарегистрировать слушателя событий для запуска кастомного кода без необходимости переопределения низкоуровневых данных. Эти события запускаются для всех видов компонентов и поведений, например: Auth, Jobs, Notifications, Commands и даже Migrations.

Понимайте фреймворк

Иначе говоря, используйте то, что предлагает фреймворк. Подражайте его паттернам и практикам. Будьте командным игроком. Не будьте изгоем.

Понимание может принимать разные формы. Одним из этих самых простых способов это директивы Blade. Laravel предоставляет десятки замечательных директив. К сожалению, многие приложения используют только стандартную директиву @if . Но есть @isset , @empty , @auth и @guest , которые могут упростить ваши шаблоны и улучшить взаимодействие.

Понимание фреймворка побуждает нас писать код как в Laravel (Laravel Way), что делает его более «домашним», доступным и, следовательно, обслуживаемым.

Другой пример — использование фасадов. Заглядывая вперед — автоматических фасадов. Фасады могут показаться сложными, поскольку приходится создавать не только базовый класс, но и принадлежность, регистрировать его в провайдере, создавать псевдоним.

Но не автоматические фасады. На самом деле мы можем использовать базовый класс в качестве фасада, просто импортируя его под динамическим пространством имен Facades. Laravel понимает класс автоматически. Это означает, что мы можем получить все преимущества фасада, включая его тестируемость.

Уважайте архитектуру MVC

Laravel — это MVC фреймворк. И он дружественен для разработчиков. Эта комбинация позволяет запросто делать такие вещи, которые размывают грань между моделями, представлениями и контроллерами. Тем не менее, важно помнить архитектуру MVC.

Как правило, в MVC при поступлении запроса контроллер выполняет посредническую функцию между моделью и представлением. Это означает ограниченную логику представления. Никакой перекрестной связи между моделью и представлением или ответом.

К сожалению, разработчики слишком часто злоупотребляют фасадами и хелперами, для получения доступа к запросам из моделей или слою даных из представлений. Опять же, фреймворки упрощают весь этот процесс. Но при этом мы связали модель не только с более высоким слоем, но и с нюансами обработки запросов Laravel или аутентификации.

Вместо этого мы можем уважать MVC и Laravel, следуя очень простому шаблону — внедрение зависимостей. Laravel внедряет объект запроса в любой метод контроллера с тайпхинтом Request . Мы также можем использовать тайпхинт объекта Form Request , если у нас есть объект, если мы хотим проверить.

Теперь мы можем передать объект запроса в модель. При этом мы уменьшаем связь только с объектом запроса. Сейчас вы можете подумать, «что в лоб, что по лбу». Возможно, но именно здесь, использованием Form Request, может свести все это вместе. Он служит контрактом, передавая данные, которым мы ожидаем от этого объекта запроса.

Пишите тесты

Даже если вы проигнорируете другие мои совет по написанию приложений, которые легко поддерживать, то вы, вероятно, сможете решить их с помощью хорошего набора тестов.

Laravel делает тестирование доступным и простым, независимо от того, какой стиль тестов вы пишете. Есть HTTP-тесты для быстрой отправки запросов в ваше приложение и проверки ответов. Есть Dusk для взаимодействия с вашим приложением через браузер. Все построено на основе PHPUnit, поэтому написание модульных тестов тоже возможно.

Как использовать стандартные события Laravel 5.3?

Немного изменяю свой предыдущий вопрос: Нужно отследить события входа (авторизации) пользователя в Laravel 5.3 . Уже знаю что есть и можно использовать стандартное события входа ‘auth.login’, и для этого события написать обработчик — я так понимаю Слушатель (Listener).
Делаю следующим образом:
1) В app/Providers/EventServiceProvider.php добавляю

2) В слушатель App\Listeners\UserEventListener в метод handle пишу код:

В результате в лог нечего не записывается!

Если же создаю свой event (UserVisitedEvent) и в EventServiceProvider.php пиши

а потом его вызываю
Event::fire(new UserVisitedEvent());
то так работает, в лог пишет «Пользователь вошел!». Документацию изучал, но о встроенных евентах информации мало нашел
В общем как использовать встроенные события?

Для чего нужны события и слушатели событий в Laravel на примере интернет-магазина?

Использую laravel 5.6 для разработки интернет-магазина и как-то не приходилось пользоваться событиями и их слушателями. Не пойму, для чего они нужны и как могут упростить разработку. В официально документации все написано как, а почему и зачем нет информации. Если можно, приведите на конкретном примере интернет-магазина, где там можно использовать эту фишку.

2 ответа 2

Если очень кратко и в двух словах, то:

События и слушатели — это реализация паттерна Observer (статья на Википедии).

Смысл в том, что у вас есть класс, в нем есть функции, вот вы хотите чтобы при вызове функций этого класса, вызывалась функция из другого класса — Вот собсна для чего и нужно.

Функция из первого класса — будет событием (а точнее её вызов)

Функция из второго класса — будет эвентом.

Вы можете подумать — что мне мешает вызвать из одной функции другую, без этих слушателей. Но это будет не совсем правильно.

Давайте на пальцах:

Самый банальный пример: пусть у нас есть класс Users , у этого класса есть метод Auth (авторизация). Т.е. этот метод отвечает за логику-авторизации, и вызывается он только тогда когда происходит успешный вход (ввод логина и пароля).

Теперь мы хотим, чтобы при входе, нам приходило письмо, что кто-то на нашем сайте вошел в систему. У нас, условно, есть класс Admin и у него метод SendMessage , который реализует данную логику. Самое первое что может прийти на ум, мы внутри метода Auth можем написать вызов класса Admin и его метода SendMessage . Но это будет не правильно, потому что в логике Auth внутри появляется сторонняя логика SendMessage (P.S. вот тут очень тонко, сложно для понимания, где логика считается раздельной, а где единой, но думаю вы понимаете). Правильней применить наш паттерн, и реализовать такую систему, где при вызове Auth вызовется наш SendMessage , не влияя на логику внутри Auth .

Почему я сказал про тонкость? Дело в том, что где-то SendMessage будет являться частью логики Auth и тогда вызов внутри функции — это нормально, а где-то нет.

Для визуального представления различий ситуации, давайте возьмем третий класс Logs с методом CreateLog — цель которого записывать(логировать) какие-то данные о нашем пользователе. Понятное дело что логировать надо не только Auth , а еще и вход, и выход, и регистрацию, и восстановление — а это все функции, если мы в каждой функции будем дописывать вызов нашего класса Logs и метода CreateLog — то как видите получится не совсем красиво, потом после отладки забудем где-то что-то удалить, или забудем где мы что писали, ходи по файликам и ищи. Собсна в такой ситуации с логированием, лучшего помощника, чем слушатель — не найти. Мы просто указываем какие функции нам нужны (события), и какую функцию вызывать.

Пользовательские события в Laravel

Russian (Pусский) translation by Ilya Nikov (you can also view the original English article)

В этой статье мы рассмотрим основы управления событиями в Laravel. Это одна из важных функций, которую вы, как разработчик, должны иметь в своем арсенале. По мере продвижения мы также воспользуемся этой возможностью, чтобы создать реальный пример пользовательского события и слушателя, и это конечная цель этой статьи.

Концепция событий в Laravel основана на очень популярном шаблоне проектирования программного обеспечения — шаблоне наблюдателя. В этом шаблоне система должна генерировать события, когда что-то происходит, и вы можете определить слушателей, которые прислушиваются к этим событиям и соответственно реагируют. Это действительно полезная функция, позволяющая отделить компоненты в системе, что в противном случае привело бы к тесно связанному коду.

Например, вы хотите уведомить все модули в системе, когда кто-то заходит на ваш сайт. Таким образом, это позволяет им реагировать на это событие входа в систему, будь то отправка электронной почты или уведомление в приложении.

Основы событий и слушателей

В этом разделе мы рассмотрим способ Laravel для реализации событий и слушателей в ядре фреймворка. Если вы знакомы с архитектурой Laravel, вы, вероятно, знаете, что Laravel реализует концепцию поставщика услуг, которая позволяет вам вводить различные сервисы в приложение.

Аналогичным образом, Laravel предоставляет встроенный класс EventServiceProvider.php , который позволяет нам определять маппинг событий для приложения.

Идем дальше и рассмотрим файл app/Providers/EventServiceProvider.php .

Давайте внимательно рассмотрим свойство $listen , которое позволяет вам определять массив событий и связанных с ними слушателей. Ключи массива соответствуют событиям в системе, а их значения соответствуют слушателям, которые будут срабатывать, когда соответствующее событие будет сгенерировано в системе.

Я предпочитаю использовать реальный пример. Как вы, вероятно, знаете, Laravel предоставляет встроенную систему аутентификации, которая облегчает такие функции, как вход в систему, регистрация и т.п.

Представьте, что вы хотите отправить уведомление по электронной почте в качестве меры безопасности, когда кто-то войдет в приложение. Если Laravel не поддерживает функцию прослушивателя событий, возможно, вы закончили бы с каким-то общим классом или каким-либо другим способом подключить свой код, который отправляет электронное письмо.

На самом деле, к счастью для вас, Laravel помогает решить эту проблему с помощью прослушивателя событий. Изменим файл app/Providers/EventServiceProvider.php , чтобы он выглядел следующим образом.

Illuminate\Auth\Events\Login — это событие, которое будет поднято плагином Auth , когда кто-то войдет в приложение. Мы связали это событие со слушателем App\Listeners\SendEmailNotification , поэтому он будет запущен при логине.

Конечно, вам необходимо определить класс слушателя App\Listeners\SendEmailNotification . Как всегда, Laravel позволяет вам создать код шаблона слушателя, используя команду artisan.

Эта команда генерирует классы событий и слушателей, перечисленные в атрибуте $listen .

В нашем случае событие Illuminate\Auth\Events\Login уже существует, поэтому он создает класс слушателя App\Listeners\SendEmailNotification . Фактически, команда создала бы класс события Illuminate\Auth\Events\Login , если бы он не существовал.

Давайте посмотрим на класс слушателя, созданный в app/Listeners/SendEmailNotification.php .

Это метод handle , который будет вызываться с соответствующими зависимостями всякий раз, когда слушатель запускается. В нашем случае аргумент $event должен содержать контекстуальную информацию о входе с пользовательской информацией.

И мы можем использовать объект $event для дальнейшей обработки в методе handle . В нашем случае мы хотим отправить уведомление по электронной почте зарегистрированному пользователю.

Обновленный handle обработки может выглядеть примерно так:

Вот как вы должны использовать функцию событий в Laravel. В следующем разделе мы продолжим работу и создадим настраиваемое событие и связанный с ним класс слушателя.

Создание пользовательского события

Сценарий, который мы будем использовать для нашего примера, выглядит примерно так:

  • Приложение должно очищать кеши в системе в определенных точках. Мы будем генерировать событие CacheClear вместе с контекстной информацией, когда приложение выполняет вышеупомянутое действие. Мы передадим ключи группы кешей вместе с событием.
  • Другие модули в системе могут прослушивать событие CacheClear и хотели бы реализовать код, который подготавливает связанные кеши.

Давайте рассмотрим файл app/Providers/EventServiceProvider.php и зарегистрируем наши пользовательские сопоставления событий и слушателей.

Как вы можете видеть, мы определили событие App\Events\ClearCache и связанный с ним класс слушателя App\Listeners\WarmUpCache в свойстве $listen .

Затем нам нужно создать связанные файлы классов. Напомним, что вы всегда можете использовать команду artisan для генерации базового шаблона кода.


Это должно было создать класс события в app/Events/ClearCache.php и классе слушателя в app/Listeners/WarmUpCache.php .

С некоторыми изменениями класс app/Events/ClearCache.php должен выглядеть следующим образом:

Как вы, наверное, заметили, мы добавили новое свойство $cache_keys , которое будет использоваться для хранения информации, которая будет передана вместе с событием. В нашем случае мы будем передавать группы кэша, которые были сброшены.

Затем давайте посмотрим на класс слушателя с обновленным методом handle в app/Listeners/WarmUpCache.php .

Когда вызывается слушатель, в метод handle передается экземпляр связанного события. В нашем случае это должен быть экземпляр события ClearCache , который будет передан в качестве первого аргумента методу handle .

Далее, это просто вопрос итерации через каждый ключ кеша и обновление связанных кешей.

Теперь у нас есть все, что нужно для проверки. Давайте быстро создадим файл контроллера в app/Http/Controllers/EventController.php , чтобы продемонстрировать, как вы могли бы сгенерировать событие.

Во-первых, мы передали массив ключей кеша в качестве первого аргумента при создании экземпляра события ClearCache .

Вспомогательная функция event используется для создания события из любого места приложения. Когда событие генерируется, Laravel вызывает всех слушателей этого конкретного события.

В нашем случае слушатель App\Listeners\WarmUpCache настроен на прослушивание события App\Events\ClearCache . Таким образом, вызывается метод handle слушателя App\Listeners\WarmUpCache , когда событие возникает из контроллера. Остальное — обновить кеши, которые были очищены!

Таким образом, вы можете создавать пользовательские события в своем приложении и работать с ними.

Что такое подписчик событий?

Подписчик события позволяет вам подписывать несколько слушателей событий в одном месте. Независимо от того, хотите ли вы логически группировать слушателей событий или хотите содержать растущие события в одном месте.

Если бы мы реализовали примеры, рассмотренные до сих пор в этой статье с использованием подписчика событий, это может выглядеть так.

Это метод subscribe , который отвечает за регистрацию слушателей. Первый аргумент метода subscribe — это экземпляр класса Illuminate\Events\Dispatcher , который можно использовать для привязки событий к слушателям с использованием метода listen .

Первый аргумент метода listen — это событие, которое вы хотите прослушать, а второй аргумент — это слушатель, который будет вызываться при создании события.

Таким образом, вы можете определить несколько событий и слушателей в самом классе подписчика.

Класс подписчика события не будет автоматически загружен. Вам необходимо зарегистрировать его в классе EventServiceProvider.php в свойстве $subscriber , как показано в следующем фрагменте.

Итак, это был класс подписчиков событий и на этом данная статья заканчивается.

Заключение

Сегодня мы обсудили пару интересных особенностей Laravel- события и слушатели. Они основаны на шаблоне проектирования наблюдатель, который позволяет вам увеличивать события на уровне приложений и разрешать другим модулям прослушивать эти события и реагировать соответствующим образом.

Вам интересен Laravel или хотите расширить свои знания, сайт или приложение с помощью расширений? У нас есть множество вещей, которые вы можете изучать на Envato Market.

Internal Server Error

Error 500

This could be due to one of the following reasons:

.htaccess file was misconfigured

Permissions for the file requested on site were misconfigured

PHP or CGI code was misconfigured in the file that is requested on site

Site resources are approaching their maximum limits

Please contact the server administrator [email protected] and provide the following information:

The time the error occurred

The actions you took prior to and immediately following the error. This will help the administrator better understand what may have caused the error. Please refer to the server error log for more information.

Events

Introduction

Laravel’s events provide a simple observer implementation, allowing you to subscribe and listen for various events that occur in your application. Event classes are typically stored in the app/Events directory, while their listeners are stored in app/Listeners . Don’t worry if you don’t see these directories in your application, since they will be created for you as you generate events and listeners using Artisan console commands.

Events serve as a great way to decouple various aspects of your application, since a single event can have multiple listeners that do not depend on each other. For example, you may wish to send a Slack notification to your user each time an order has shipped. Instead of coupling your order processing code to your Slack notification code, you can raise an OrderShipped event, which a listener can receive and transform into a Slack notification.

Registering Events & Listeners

The EventServiceProvider included with your Laravel application provides a convenient place to register all of your application’s event listeners. The listen property contains an array of all events (keys) and their listeners (values). You may add as many events to this array as your application requires. For example, let’s add a OrderShipped event:

Generating Events & Listeners

Of course, manually creating the files for each event and listener is cumbersome. Instead, add listeners and events to your EventServiceProvider and use the event:generate command. This command will generate any events or listeners that are listed in your EventServiceProvider . Events and listeners that already exist will be left untouched:

Manually Registering Events

Typically, events should be registered via the EventServiceProvider $listen array; however, you may also register Closure based events manually in the boot method of your EventServiceProvider :

Wildcard Event Listeners

You may even register listeners using the * as a wildcard parameter, allowing you to catch multiple events on the same listener. Wildcard listeners receive the event name as their first argument, and the entire event data array as their second argument:

Event Discovery

Event Discovery is available for Laravel 5.8.9 or later.

Instead of registering events and listeners manually in the $listen array of the EventServiceProvider , you can enable automatic event discovery. When event discovery is enabled, Laravel will automatically find and register your events and listeners by scanning your application’s Listeners directory. In addition, any explicitly defined events listed in the EventServiceProvider will still be registered.

Laravel finds event listeners by scanning the listener classes using reflection. When Laravel finds any listener class method that begins with handle , Laravel will register those methods as event listeners for the event that is type-hinted in the method’s signature:

Event discovery is disabled by default, but you can enable it by overriding the shouldDiscoverEvents method of your application’s EventServiceProvider :

By default, all listeners within your application’s Listeners directory will be scanned. If you would like to define additional directories to scan, you may override the discoverEventsWithin method in your EventServiceProvider :

In production, you likely do not want the framework to scan all of your listeners on every request. Therefore, during your deployment process, you should run the event:cache Artisan command to cache a manifest of all of your application’s events and listeners. This manifest will be used by the framework to speed up the event registration process. The event:clear command may be used to destroy the cache.

The event:list command may be used to display a list of all events and listeners registered by your application.

Defining Events

An event class is a data container which holds the information related to the event. For example, let’s assume our generated OrderShipped event receives an Eloquent ORM object:

As you can see, this event class contains no logic. It is a container for the Order instance that was purchased. The SerializesModels trait used by the event will gracefully serialize any Eloquent models if the event object is serialized using PHP’s serialize function.

Defining Listeners

Next, let’s take a look at the listener for our example event. Event listeners receive the event instance in their handle method. The event:generate command will automatically import the proper event class and type-hint the event on the handle method. Within the handle method, you may perform any actions necessary to respond to the event:

Your event listeners may also type-hint any dependencies they need on their constructors. All event listeners are resolved via the Laravel service container, so dependencies will be injected automatically.

Stopping The Propagation Of An Event

Sometimes, you may wish to stop the propagation of an event to other listeners. You may do so by returning false from your listener’s handle method.

Queued Event Listeners

Queueing listeners can be beneficial if your listener is going to perform a slow task such as sending an e-mail or making an HTTP request. Before getting started with queued listeners, make sure to configure your queue and start a queue listener on your server or local development environment.

To specify that a listener should be queued, add the ShouldQueue interface to the listener class. Listeners generated by the event:generate Artisan command already have this interface imported into the current namespace, so you can use it immediately:

That’s it! Now, when this listener is called for an event, it will be automatically queued by the event dispatcher using Laravel’s queue system. If no exceptions are thrown when the listener is executed by the queue, the queued job will automatically be deleted after it has finished processing.

Customizing The Queue Connection & Queue Name

If you would like to customize the queue connection, queue name, or queue delay time of an event listener, you may define the $connection , $queue , or $delay properties on your listener class:

Conditionally Queueing Listeners

Sometimes, you may need to determine whether a listener should be queued based on some data that’s only available at runtime. To accomplish this, a shouldQueue method may be added to a listener to determine whether the listener should be queued and executed synchronously:

Manually Accessing The Queue

If you need to manually access the listener’s underlying queue job’s delete and release methods, you may do so using the Illuminate\Queue\InteractsWithQueue trait. This trait is imported by default on generated listeners and provides access to these methods:

Handling Failed Jobs

Sometimes your queued event listeners may fail. If queued listener exceeds the maximum number of attempts as defined by your queue worker, the failed method will be called on your listener. The failed method receives the event instance and the exception that caused the failure:

Dispatching Events


To dispatch an event, you may pass an instance of the event to the event helper. The helper will dispatch the event to all of its registered listeners. Since the event helper is globally available, you may call it from anywhere in your application:

When testing, it can be helpful to assert that certain events were dispatched without actually triggering their listeners. Laravel’s built-in testing helpers makes it a cinch.

Event Subscribers

Writing Event Subscribers

Event subscribers are classes that may subscribe to multiple events from within the class itself, allowing you to define several event handlers within a single class. Subscribers should define a subscribe method, which will be passed an event dispatcher instance. You may call the listen method on the given dispatcher to register event listeners:

Registering Event Subscribers

After writing the subscriber, you are ready to register it with the event dispatcher. You may register subscribers using the $subscribe property on the EventServiceProvider . For example, let’s add the UserEventSubscriber to the list:

Become a Laravel Partner

Laravel Partners are elite shops providing top-notch Laravel development and consulting. Each of our partners can help you craft a beautiful, well-architected project.

Работа с событиями в Laravel. Асинхронная обработка очереди.

В ней мы ознакомились с механизмом событий в Laravel, на примере отправки push-уведомления при публикации поста в блоге. Код который мы произвели на свет оказался не идеален:

1) отправка у нас происходит в реальном времени при сохранении модели, если добавятся более тяжелые и медленные операции, до сохранения не дойдет и все упадет.

2) при записи статуса отправки мы не учитываем ответ сервиса, если сервис откажет в отправке, мы статью посчитаем обработанной и больше по ней пытаться отправить уведомления не будем.

Давайте исправлять ситуацию.

Переосмысливаем архитектуру.

Очевидно мы избрали не самый верный путь. Нам необходима асинхронная обработка нашего события. Для этого событие нужно поставить в очередь. Подробнее об очередях можно почитать в официальной документации.

Для работы с очередями у Laravel есть несколько драйверов для специально-обученного ПО: Beanstalkd, Amazon SQS, Redis. Но есть и родной механизм для использования БД. На нем и остановимся, как на самом простом варианте, не требующим установки ПО и использования внешних сервисов.

Настройка.

Укажем в конфиге, что хотим обрабатывать очереди через БД, в .env пропишем QUEUE_DRIVER=database

Создадим и выполним миграцию для создания таблиц очереди.

В БД должна появиться таблица jobs, в которой будут храниться наши события.

Поставить событие в очередь в Laravel проще простого.

Необходимо лишь чтобы наш слушатель реализовал интерфейс Illuminate\Contracts\Queue\ShouldQueue.

Таким образом: class PostActionsListener implements ShouldQueue

Тестируем

Напишем такой метод для проверки получает ли очередь задание

Заодно добавим в самое начало тест на простую проверку сохранения поста, у нас такого не было.

1) PostCreateTest::testPostCreate Illuminate\Database\Eloquent\ModelNotFoundException: No query results for model [App\Models\Post].

Что это? и почему произошло?

Суть ошибки в том, что модель не может быть найдена и судя по стеку

Это происходит при сериализации модели для очереди.

Вот в чем загвоздка! Мы же бросаем событие перед сохранением объекта в БД. Давайте срочно это исправим, тем более, что сама идея обращаться в сторонние сервисы по API перед сохранением объекта — довольно рискованная.

Меняем saving на saved. Заодно убираем установку статуса публикации. Она переедет в другое место.

Запускаем phpunit, все отлично OK (5 tests, 3 assertions)

Можно сохранить реальный пост со статусом «Опубликован» и посмотреть, что записалось в таблицу jobs

Обработка очереди

Теперь необходимо обработать задание из очереди. Согласно документации сделать это можно либо с помощью запуска обработчика или демона, который будет в реальном времени (либо с указанным таймаутом) обрабатывать поступающие задания php artisan queue:listen , либо вызывать обработку одного задания php artisan queue:work

Поступим вторым способом, потому что событий у нас будет немного, мониторить «не умер ли давно обработчик наш» не хочу, а демонов на php я боюсь ))

Так что давайте будем запускать php artisan queue:work каждые 5 минут и все.

Настройка задач по расписанию

В Laravel есть замечательний шедулер, позволяющий практически мгновенно добавить новую задачу для выполннения по расписанию, при этом не надо помнить эти ужасные крон-выражения, почти все ситуации описываются с помощью «говорящих методов».

Но для начала надо один раз в cron добавить выполнение самого шедулера раз в минуту. crontab -e Добавляем:

Теперь идем в app/Console/Kernel.php И добавляем задание:

Тесты

Похоже полноценно протестировать очереди простыми средствами не получится. Придется тестировать функционально, ручками.

Но как же быть с уведомлениями, которые свалятся всем? В API onesignal никакого тестового режима я не нашел. Поэтому можно поступить одним из следующих образов:

  • Опубликовать тест, с датой публикации в будущем. Зайти в админку onesignal и удалить из очереди задание.
  • Завести признак рассылки уведомлений в статьях (Не рассылать/Только мне/Всем)
  • Завести параметр в конфиге.

Поступим последним образом. Добавим в config/onesignal.php ‘is_test’ => env(‘ONESIGNAL_IS_TEST’,1) В .env переопределение параметра ONESIGNAL_IS_TEST=1

И внесем правки в app/Handlers/OneSignalHandler.php Заодно переделаем его единственный метод в static

Не забудем заодно и исправить его вызов в app/Listeners/PostActionsListener.php

А как же статус отправки?

Я уже собрался закончить этот урок, когда вспомнил про статус отправки уведомления в статье. Мы его предали анафеме убрали из события перед сохранением, чтобы позже перенести запись статуса непосредственно по итогам общения с API сервиса.

По идее можно добавить установку статуса статьи в самом хендлере

Но это в корне неверно!

Компонент отправки уведомления не должен напрямую менять данные модели. Это не его зона ответсвенности!

Верный способ, исходя из выбранного нами подхода &ldash; кинуть здесь еще одно событие, говорящее о том, что уведомление ушло успешно.

Событие порождающее событие 🙂

Идем опять в app/Providers/EventServiceProvider.php Добавляем в $listen

В консоли php artisan event:generate

В созданном событиии, по образу и подобию предыдущего события, добавим проперти $post

В слушателе сделаем обработку события — запись статуса. Саму запись статуса оформим в виде метода в Post

Бросим событие в хендлере уведомлений

Все. Можно тестировать!

Заключение. В чем преимущества событий

На этом все, в следующий раз добавим отправку текста в «оригинальные тексты» яндекса и публикацию в соцсетях.

В чем же преимущество событийной архитектуры?

Само событие и его обработка у нас разделены, по сути мы реализуем слабосвязанную архитектуру через микросервисы, что позволяет делает наше приложение более гибким и легко расширять и тестировать его.

Нам не нужно помнить где конкретно происходит событие при добавлении нового функционала в его обработку.

Да, в нашем простом примере, это одно место в коде, но в реальном проекте могут быть десятки мест, в которых это событие происходит: вызов апи, обработка роутинга, входящих данных, сообщений электронной почты и тд. И десятки слушателей его могут обрабатывать.

Но есть и обратная сторона луны: с ростом такого приложения, когда количество событий в нем и их обработчиков разрастается, поддержка такого проекта может превратиться в весьма нетривиальную задачу.

Использовать события в реальной жизни или нет, решать вам.

Но знать о них уж точно надо!

Топ-пост этого месяца:  Как удалить все товары в OpenCart
Добавить комментарий