Events vs Observers in laravel - php

I'm really confused with events and observers. because both are doing same things. what are the differences b/w events and observers? Thanks in advance.

Observers and events do not do the same thing at all.
Simple Difference
Observers are basically predefined events that happen only on Eloquent Models (creating a record, updating a record, deleting, etc). Events are generic, aren't predefined, and can be used anywhere, not just in models.
Observers:
An observer watches for specific things that happen within eloquent such as saving, saved, deleting, deleted (there are more but you should get the point). Observers are specifically bound to a model.
Events:
Events are actions that are driven by whatever the programmer wants. If you want to fire an event when somebody loads a page, you can do that. Unlike observers events can also be queue, and ran via laravel's cron heartbeat. Events are programmer defined effectively. They give you the ability to handle actions that you would not want a user to wait for (example being the purchase of a pod cast)
The documentation does a very good job covering these.
Reference Taken From : https://www.scratchcode.io/laravel/difference-between-events-and-observers-in-laravel/

OK. So, clear up one thing Events and Observers are not doing same things.
What is Event ?
Event is triggered when specific task happens. Such as, some model is created, updated, delete (these are the default ones from laravel). You can dispatch/trigger your custom events as well product.liked or user.commented.
https://laravel.com/docs/5.7/events#defining-events
What are observers ?
As name states these classes observes/handles those events above mentioned. So if we say
we want to do something when user is created or user is creating (this is before making an entry to DB). We define observers and if you are familiar with before and after methods methodology you can relate.
https://laravel.com/docs/5.7/eloquent#observers

Related

On a laravel app is it possible to have listener called only once, no matter how many times an event is being fired?

I think the title says it all.. In a Laravel app I'm dispatching an event (or events) multiple times in the code and have a subscriber for them, but I want it to process only once, no matter how many times the events are fired in the flow.
Is there any clear way to do that, or I am going to need a ..singleton class or something like that?
Thanks
You could unlisten the event with Event::forget('YourEvent'); in the subscriber after the first dispatch.
The downside is that all other listeners of this event will also be removed.

Naming of Listeners in Symfony2

I've read some guides / tutorials about Symfonys event system. But I am still not sure about the naming best practice. Unfortunatelly most documentations use default scenarios like login, etc. So here is an example from a game:
A command evaluations some kind of match result. It fires an appropriate event like this:
$dispatcher->dispatch('game_bundle.match_won', new MatchWonEvent($match, $winner));
Now I want to register several listeners to handle this event, like for example one for posting this to the winner's Facebook page and another one to book an achievement for the winner. In the examples I found the listener handling the login event was mainly called something like LoginListener, but shouldn't this name relate to the actual use of it instead of the event it is related to? Because now in my example I would need a MatchWonListener, but should that contain both the Facebook and the achievement logic? That would make the event system useless then... Wouldn't it be better to have one FacebookListener with an onMatchWon($event) and one AchievementListener with it's own onMatchWon($event) method? This would also make it easy to add more Facebook-related events into the FacebookListener for example.
I am confused about the naming in the samples and not sure about now. Am I getting it totally wrong?
There's no "best practice" on how to name events. However, if you name the listener after the event, I think that defeats the purpose of events altogether. The goal is to be able to let different parts of your system interact between each other without coupling and mixing concerns.
So considering you went this far of creating events to separate concerns, why would you go and mix all the different logics into one listener? In that case you might as well just do a direct call instead of dispatching an event.
I'm personally against names like "onMatchWon" because that doesn't describe what the method does. Let's say you want to listen to a match won event and update the achievements of the user who won. I'd probably have some user manager service or the sort with a method updateAchievements(MatchWonEvent $event). But I think that's more of a matter of taste, or convention if you're willing to.

Create Project Log(History) Module in symfony with event dispatchers

I'm developing a project management tool in Symfony, right now I'm creating a module to recording the logs i.e, to capture every event like New project create, task create, task status changes, deletion of projects and task, etc.
I have a log table where I have planned to insert new rows whenever any of the above event occurs. But for doing this, I need to go into each controller and call the log model to execute the insert query. Its almost like I'm going to work on all the actions in the controller again for appending this code. is there any other way to call the model only once using some event dispatcher like class in Symfony.
Glad your are using Propel, there is a bunch of plugins and/or behavior for tracking what happend to your object. I will give you a list of what I've found:
pmPropelObjectLogBehaviorPlugin: Maintains a class changelog (the changes of each instance).
AuditableBehavior: Add ability to log activity for propel objects
propel-listener-behavior: Makes you attach listeners to propel generated objects that inform you about updates on those.
ncPropelChangeLogBehaviorPlugin: a Behavior for Propel objects that allows you to track any changes made to them.
JMSAOPBundle does exactly that.
If I may suggest, I think it's better to add custom events for each action, with this way you can extend your app with more listener without losing control. If you use doctrine you can also work with doctrine event system

How to implement a full Observer pattern in PHP

An Observer Design Pattern is the solution to loosely coupling objects so they can work together. In PHP you can easily implement this using just two classes.
Basically, you have a subject which is able to notify and update a list of observers of its state changes.
The problem I'm trying to solve is to know how to handler alerting the observers about different states of the object they are watching.
For example, lets say we have a file upload class to which we attach a logging class, websockets class, and a image resize class. Each of these classes that are watching want to know about different events in the upload process.
This file upload class might have three places where it needs to notify the classes listening that something has happend.
Error With Upload (alert logging class)
Upload success (alert websockets class)
Upload success and is image file (alert image resize class)
This is a very basic example, but how do you handle multiple events that different observers may need to know about? Calling notifyObservers() alone wouldn't be enough since each observer needs to know what it is being notified about.
One thought is that I could state with the call what type of event is being observed:
$this->notifyObservers('upload.error', this);
However, that would mean I would have to add custom switching to the observers themselves to know how to handle different events.
function observe($type, $object)
{
if($type === 'upload.error') $this->dosomething();
elseif($type === 'something.else') $this->otherthing();
...etc...
}
I find that very ugly as it starts to couple the observers back to the class they are observing.
Then again, if I just notify Observers without passing any information about what event just happens - they have to guess themselves what is going on which means more if() checks.
The observers aren't actually coupled to the class they are observing. The connection between the observer's handler and the observed object is made using literal string values (e.g. `upload.error'), which means that:
If you want to observe a specific object, you have to know from beforehand the names of the events it will publishing; this is the "coupling" that you don't like.
On the other hand, if you are interested in a specific event only, you can observe any type of object for that event without having any knowledge about that object.
Item 2 above is a benefit that you care about, but what to do about item 1?
If you think about it, there needs to be some way to differentiate between callbacks to the same observer if they represent different events taking place. These "identifiers", no matter what form they take, need to be packaged either into the observed object or be a part of the observer library code.
In the first instance (inside observed object) you would probably need a way for observers to query "do you ever publish event X?" before starting to observe a target for that event. The target can answer this question just fine. This leaves a bitter taste of coupling, but if you want any object to observe any other, and you have no idea what you will be observing beforehand, I don't think you can do any better.
In the second approach, you would have a number of well-known events defined (as const inside a class?) in your library. Presumably such a list of events can be made because the library tackles a concrete application domain, and that domain offers obvious choices for the events. Then, classes both internal to your library (which would end up being observed) and external to it (the observers which plug into the framework) would use these identifiers to differentiate between events. Many callback-based APIs (such as Win32) use an approach practically identical to this.

Observer Design Pattern - multiple event types

I'm currently implementing the Observer design pattern and using it to handle adding items to the session, create error logs and write messages out to the user giving feedback on their actions (e.g. You've just logged out!).
I began with a single method on the subject called addEvent() but as I added more Observers I found that the parameters required to detail all the information I needed for each listener began to grow.
I now have 3 methods called addMessage(), addStorage() and addLog(). These add data into an events array that has a key related to the event type (e.g. log, message, storage) but I'm starting to feel that now the subject needs to know too much about the listeners that are attached.
My alternative thought is to go back to addEvent() and pass an event type (e.g. USER_LOGOUT) along with the data associated and each Observer maintains it's own list of event handles it is looking for (possibly in a switch statement), but this feels cumbersome. Also, I'd need to check that sufficient data had also been passed along with the event type.
What is the correct way of doing this?
Please let me know if I can explain any parts of this further. I hope you can help and see the problem I'm battling with.

Categories