
Asynchronous PHP. What for?
- Transfer

Asynchronous programming is in demand today, especially in web development, where application responsiveness is especially important. Nobody wants to wait until the application “sags”, even if at that time it executes a query to the database, sends an email or works on other tasks that can take a lot of time. The client wants an answer to his action, best of all - right away. If your application is slow, you are losing customers. Faced with a hovering application, most often the user simply closes it and never returns. From the point of view of the user, the application just hung, he can’t understand why this happened: does it perform a complex operation or ceased to work in principle.
Introducing the translation of an article by Skyeng backend developer Sergey Zhuk.
App Responsiveness
Modern applications are often responsive, but some tasks or operations, such as exchanging data over a network, file I / O, or querying a database, can be time consuming and significantly slow down the application. To prevent such operations from blocking the application, you can run them in the background, thereby hiding the delay that they cause. At the same time, the application remains responsive because it can continue to perform other tasks, for example, returning the control flow to the user interface or responding to other events.
Concurrency and Asynchrony
When people see asynchronous code, most often they immediately think: “Great, I can parallelize the processes!”. I may disappoint you, but in fact it is not. Asynchrony and concurrency are not the same thing. It can be difficult to catch this difference, so let's try to figure it out.
If tasks are performed asynchronously, they do not block each other and the execution of one task does not depend on the completion of another. Concurrency, in turn, implies the launch of several separate tasks simultaneously as independent units of work.
Asynchrony:
Go and complete the task yourself . Let me know when you're done and show me the result. At this time, I can continue to do my job.
Asynchronous code requires the processing of dependencies that arise during the execution of tasks, and this is implemented using callbacks. When a task is completed, the code notifies another task. Asynchronous code is basically about the time the task takes to complete (order of events).

Parallelism:
Hire as many workers as you want, and share the task between them to complete it faster, and notify me when you are done. I can continue to do other things or, if the task is urgent, I will stay and wait until you return with the results. Then I can compose the final result from all the employees. Parallel execution often requires more resources, so here it basically depends on the hardware.

To understand the difference between asynchronous and parallel execution using a real-life example, we compare two popular web servers: Apache and Nginx. They perfectly illustrate this difference. Nginx uses an event-based asynchronous model while Apache uses parallel threads. Apache creates new threads for each additional connection, so here the maximum number of allowed connections depends on the amount of available memory in the system. When the connection limit is reached, Apache stops creating additional connections. The limiting factor when configuring Apache is memory (remember that parallel execution often depends on hardware). If the thread stops, the client waits for a response until the thread is free and can send a response.
Nginx does not work like Apache - it does not create new threads for every incoming request. Nginx has a main workflow (or several workers, often for one processor there is one workflow), which is single-threaded. This worker can process thousands of connections "simultaneously" and does it asynchronously, in one thread, and not in parallel in several threads.
Thus, “asynchrony” is how we build the system, it is a composition of processes independent of each other. By "parallel execution" is meant the execution of several processes at the same moment in time, while they may or may not be related. In asynchronous execution, we process several tasks at once, and in parallel execution, we start several processes at once. This may seem to be the same thing, but it is not. Asynchrony describes the structure, parallelism describes the way of execution.
Asynchronous execution can be compared to I / O devices on your computer (mouse, keyboard, display). They are all managed by the operating system, but each of them is an independent part of the kernel. These processes are asynchronous, they can be parallel, but this is not necessary. Thus, in order to ensure consistency, you must create a link between these independent parts in order to coordinate them.
What about this backend?
You can say that responsiveness is not that important on the backend. All these cool asynchronous things with JavaScript happen on a freeend, and your server just responds to requests, so a freeend should be responsible for the responsiveness of the application, but not you. Yes, that’s true, but the server’s task is not limited to API responses. Sometimes you have to manage complex tasks, for example, downloading a video. In this case, responsiveness may not be a key factor, but its lack of resources is wasted because the application has to be idle. It can wait for the completion of file system operations, network interactions, database queries, and the like. Often these I / O operations are very slow compared to processor calculations, for example when we convert video files. And while we slowly save or read the file, the processor is forced to standby instead of doing useful work. As we already found out, instead of waiting, we can run these tasks in the background. How? Move on.
Asynchronous PHP
In JavaScript, out of the box, built-in support and solutions for writing asynchronous code are available. There is also Node.js, which allows you to write asynchronous server applications. In JavaScript, we can use the setTimeout () function to demonstrate an example of asynchronous code:

When we run this code, we will see the following:

The setTimeout () function sends the code to the queue and executes it at the end of the current call stack. This means that we disrupt the synchronous flow of code and delay execution. The second call to console.log () is performed before the call to the queue inside the setTimeout () call.
What about PHP? In PHP, we do not have suitable adapted tools for writing truly asynchronous code. There is no equivalent to setTimeout (), and we cannot simply delay or queue any code. That's why frameworks and libraries like Amp and ReactPHP began to appear. Their idea is to hide low-level language details and give the user high-level tools that allow you to write asynchronous code and control the competitive execution of processes like JavaScript and Node.js.
Why should I use PHP if there is Node.js and Go?
This question often arises when it comes to asynchronous PHP. For some reason, many are against using PHP to write asynchronous code. Someone always suggests using Go or Node.js. instead of PHP.
The assertchris tweet perfectly describes such situations:

Of course, when PHP was just being created, there was no purpose to make it a programming language that can be used to create large complex applications. At that time, no one thought about JavaScript or asynchrony. But now we have a completely different PHP that already has its own functions for writing asynchronous code (for example, the stream_select () function).
Yes, you can use Go or Node.js to create asynchronous server applications, but this does not always solve the problem. If you already have extensive experience with PHP, it will be much easier for you to simply learn the libraries and tools that are appropriate for your situation than to learn a new language and a new ecosystem. Tools like ReactPHP or Amp allow you to write asynchronous code just like you do it in Node.js. These tools are quite developed and have stable versions, so you can safely use them in production.
Not just CLI
I am not going to write a chat, server or something like that. I just want to speed up the site.
It is generally accepted that asynchronous code can only be used in CLI scripts. It is absolutely normal to integrate some asynchronous components into a traditional synchronous environment, even into a traditional web application. For example, you can receive a request and then call several different resources asynchronously, and when these calls are completed, you can continue the request-response life cycle, and as a result, the page will display faster.
Or you need to make some external API calls - for example, when a user completes a payment, you want to send an email or a push notification. You can make these API calls asynchronously, and then continue your traditional synchronous code stream. There is no need to completely rewrite the application and delete everything that slows down. Just identify bottlenecks that interfere with performance, and it’s possible they can be fixed using asynchronous code.
Yes, asynchronous code is in most cases still used in CLI scripts, but it is not limited to real-time chats and servers. If you just want to speed up your site, you don’t need to give up your Symfony or Laravel framework and create your own completely asynchronous application server.
Conclusion
Do not be afraid to learn a new paradigm. PHP is much more than “run a script, execute code, and die.” You will be surprised when you realize that you can use the familiar PHP in a completely new way, like you never used it! Asynchronous code and event-oriented programming will expand your understanding of PHP and the possibilities of using this language. You don’t need to learn a new language for writing asynchronous applications just because “PHP is an inappropriate tool” or “I have always done this, it cannot be improved.” Just give it a try!
Well, we also remind you that we always have a lot of interesting vacancies for developers!