Tools php event about

What is ReactPHP

PHP was born in the 90s and was a very powerful tool for creating web pages. From its born it has a synchronous run-time, that means that we start execution of some function, and the code flow is blocked until this function is being executed. And it was not considered as something bad. On the opposite many libraries consider that the blocked flow is normal. They assume that the PHP code is written in the imperative way when one command usually follows another and it is normal if something blocks the flow. For example, let’s consider the traditional request-response cycle. The client opens a web page in the browser and the browser sends a request to the web server. The web server searches for the files that match the requested one. Then the web server looks into the file, if it finds PHP code there it processes this file. The PHP script itself may interact with the database to receive some data from it or to store some data. Then PHP produces the final HTML which is going to be returned to the client.

cgn-edit

So, when you make a request to your database and have to wait some seconds to get the results we can assume that it is OK because the next commands in the script need these results. In the request-response lifecycle, it can be considered OK. But this approach makes PHP slow because we have to wait.

But since the 90th the world has changed a lot. Now PHP is something more than a simple script, which is used to render a web page in the request-response cycle:

  • Live Data (continuously auto-updating feed/chat)
  • HTTP APIs (RESTful)
  • Integration with 3rd party clients
  • Command Line Interface tools

And here ReactPHP enters the game… The main idea behind React is:

calculations are fast, input/output is slow.

I/O operations are extremely slow compared with the CPU calculations. For example, when we talk about CPU operations we use nanoseconds, but when we deal with the network communication we often consider milliseconds. Simply try to ping google.com:

cgn-edit

Implementations

ReactPHP provides several implementations of the event loop depending on what extensions are available in the system. The most convenient and recommended way to create an instance of the loop is to use a factory:

cgn-edit

A periodic timer is registered with the event loop. Then we start event loop with $loop->run() , when a timer is fired the code flow leaves an event loop and a timer code is being executed. Every two seconds, the timer displays an increasing number. Event loop will run endlessly.

Читайте также:  Html prefix og http

A callback can accept an instance of the timer, in which this callback is executed:

After the fifth execution, this timer will be detached. When event loop is empty it stops:

Timers can interact with each other. Both methods addTimer and addPeriodicTimer return an instance of the attached timer. Then we can use this instance and pass it to the callback of the another timer. This way we can specify a timeout for some event:

 $loop = React\EventLoop\Factory::create(); $counter = 0; $periodicTimer = $loop->addPeriodicTimer(2, function() use(&$counter, $loop)  $counter++; echo "$counter\n"; >); $loop->addTimer(5, function() use($periodicTimer, $loop)  $loop->cancelTimer($periodicTimer); >); $loop->run();

In the snippet above the periodic timer will be executed only first 5 seconds, after that, it will be detached from the event loop.

Notice. Since all the timers are executed in the same thread, you should be aware of blocking operations in the callbacks. One blocking timer can stop the whole event loop like this:

 $loop = React\EventLoop\Factory::create(); $i = 0; $loop->addPeriodicTimer(1, function() use (&$i)  echo ++$i, "\n"; >); $loop->addTimer(2, function ()  sleep(10); >); $loop->run();

The first periodic timer will wait for 10 seconds until the second one-off timer will be executed.

Conclusion

Whenever you have to wait for something (network, filesystem input/output operations) — consider ReactPHP. You don’t have to use it but consider. All these tools allow to start or to defer operations and to get a notification whenever something interesting happens. The main loop is the only thing that is going to be blocking. It has to check for the events, so it could react for the incoming data. When we execute for example sleep(10) , the loop will not be executed during these 10 seconds. And everything that loop is going to do during this time will be delayed by these seconds. Never block the loop, for situations when you need to wait, you should use timers.

Timers can be used to execute some code in a delayed future. This code may be executed after the specified interval. Each timer is being executed in the same thread as the whole event loop, so any timer can affect this loop. Timers can be useful for non-blocking operations such as I/O, but executing a long living code in them can lead to the unexpected results.

Also, everything that could take longer than about one millisecond should be reconsidered. When you cannot avoid using blocking functions the common recommendation is to fork this process, so you can continue running the event loop without any delays.

This post was inspired by Christian Lück and his conference talks:

You can find examples from this article on GitHub.

This article is a part of the ReactPHP Series.

Learning Event-Driven PHP With ReactPHP

The book about asynchronous PHP that you NEED!

A complete guide to writing asynchronous applications with ReactPHP. Discover event-driven architecture and non-blocking I/O with PHP!

Источник

Event Handling — PHP

Event Handling - PHP

John was assigned with user registration issue. He wanted to avoid this issue, because of complexity level that was related to this code. He was working in the project for two years and he was already fixing it for several times, however whenever he opened the code, it was like he would see it for the first time.

John was picking any other issue, delaying the registration problem to the last possible minute. He was sweating, whenever his supervisor was asking about the issue. So after several days, he decided to refactor the code, to make his work easier.

Have you ever worked on the code that was doing so much, that it was scary to change it?Or have you analyzed it from the beginning whenever you opened it?

This often comes from the code full of Sub Flows, which have been merged with the Main Flow.

Main Flow and Sub Flows

In case of the registration Main Flow would be creating an user and saving it to the database.
The Sub Flows on other hand could be:
— Sending an welcome or confirmation email
— Creating audit logs about user registration
— Synchronizing registered user to external Service

If we will look on registration (creating and saving the user) as the main flow, the sub flows happens as a result of main flow being successful.

So how do we tell that the main flow was successful?
We are doing it by Events!

Event is describing that something happened in the past. In case of the registration it would be that User Was Registered.
By subscribing to Event, we are able to run any Sub Flow.

Publishing and Subscribing to Event

Let’s start by defining Event Class.

We will publish the PersonWasRegistered event using Event Bus from PersonRegistrationService.

We can now move all the logic to Event Handlers, which subscribe to specific event.

The Event Handler subscribes to specific event based on first parameter type hint.

We have used a single class here that contains of three Event Handlers.
You are free to create separate classes for each Event Handler, if you feel the need.

You could notice, that we are injecting specific Service directly into Event Handler’s method.

This is possible due to Ecotone’s Method Invocation mechanism. You may pass any services to given Command/Event/Query Handler’s method, and Ecotone will do the work by injecting those services for you.

Happy John

John is sure now, that separating sub flows will make his code more readable, testable and solid.
He sees that changing the code for given functionality will only affect given flow now.
He can think of much easier testing as he can test Event Handlers separately and in isolation.
And is sure, that it will be easier for the team to maintain the code in the future when new sub flows will arrive.

If you want to read more about Event Handling, follow the Ecotone’s documentation.

Sign up for more like this.

Building Blocks: Exploring Aggregates, Sagas, Event Sourcing

Building Blocks: Exploring Aggregates, Sagas, Event Sourcing

Learn how building blocks enable developers to build domain-focused applications while abstracting away the complexities of integration.

Revolutionary BOA Framework: Ecotone

Revolutionary BOA Framework: Ecotone

Ecotone will change the way PHP application development is perceived thanks to enabling architecture oriented on the business.

Building Reactive Systems in PHP

Building Reactive Systems in PHP

I believe applications in 2023 and beyond should be able to self-heal, isolate failures so they don’t cascade on other components, and provide us with help to get back on track when unrecoverable error happens. They should help the developer on the design level when adding new features without

Источник

Saved searches

Use saved searches to filter your results more quickly

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

A simple, lightweight, intuitive, chainable event handling interface

License

PHPPowertools/Event

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Sign In Required

Please sign in to use Codespaces.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching Xcode

If nothing happens, download Xcode and try again.

Launching Visual Studio Code

Your codespace will open once ready.

There was a problem preparing your codespace, please try again.

Latest commit

Git stats

Files

Failed to load latest commit information.

README.md

PHPPowertools is a web application framework for PHP >= 5.4.

PHPPowertools/Event is the third component of the PHPPowertools that has been released to the public.

The purpose of this component is to provide a PHP-based event handling interface similar to both NodeJS’s EventEmitter and your browser’s EventTarget.

use \PowerTools\Event_Emitter as Event_Emitter; // Define some event handlers $eventHandlers = [ 'handler1' => function($a = '', $b = '') < // var_dump($this); echo 'handler1 fired with parameters "' . $a . '" and "' . $b . '"
'
; >, 'handler2' => function($a = '', $b = '') < // var_dump($this); echo 'handler2 fired with parameters "' . $a . '" and "' . $b . '"
'
; >, 'handler3' => function($a = '', $b = '') < // var_dump($this); echo 'handler3 fired with parameters "' . $a . '" and "' . $b . '"
'
; >, 'handler4' => function($a = '', $b = '') < // var_dump($this); echo 'handler4 fired with parameters "' . $a . '" and "' . $b . '"
'
; > ]; // Create an instance of the Event_Emitter class $emitter = Event_Emitter::factory(); // Add your event handlers to your Event_Emitter instance for the 'go' event. $emitter->addListeners('go', $eventHandlers); // Emit the 'go' event, with parameters 'FOO' and 1. $emitter->emit('go', 'FOO', 1); // Remove the second event handler for the 'go' event $emitter->removeListener('go', $eventHandlers['handler2']); // Remove ALL listeners for the 'go' event $emitter->removeAllListeners('go');
  • addListener
  • addListeners (1)
  • once
  • removeListener
  • removeListeners (1)
  • removeAllListeners
  • setMaxListeners
  • getMaxListeners
  • listeners
  • emit
  • listenerCount
  • dispatch
  1. These methods have no equivalent in either NodeJS’s EventEmitter or your browser’s EventTarget.

Источник

Оцените статью