Async-or-swim evolution? Asynchronous PHP: Non-Blocking Code Execution
Before we go anywhere, let’s just cover off the difference between synchronous and asynchronous code execution.
Synchronous: This refers to code execution where tasks are sequentially, one after another, worked through where the current task must be completed before the next one can begin.
Asynchronous: Refers to code executuions that are initiated and run concurrently without having to wait for the previous task to finish. This allows other tasks to be processed in the meantime.
Why would Asynchronous be beneficial? 👂
- Improved performance: A major benefit is the ability to make non-blocking database calls, HTTP requests or file system operations. By not waiting on these tasks, server resources can be used more efficiently, often resulting in faster response times.
- Concurrency: PHP scripts often have to perform multiple tasks that don’t depend on one another. With asynchronous programming, these tasks can run concurrently, speeding up the overall execution.
- Better User Experience: In web applications, asynchronous operations can lead to a more responsive user interface, enhancing the user experience. Historically, this is where a JavaScript library such as axios or jQuery would be used to leverage AJAX requests to execute PHP code.
Tools for Asynchronous PHP 🛠️
- ReactPHP: is a low-level library to write asynchronous code using an event-driven approach. It provides components to handle common tasks like HTTP clients/servers and file system operations.
- Swoole: is an extension to PHP that enables async, coroutines, and fibers. It’s particularly well-suited for building microservices or task schedulers.
- Amp: is a library that uses generators to make asynchronous code feel like synchronous code, simplifying the way developers write and think about async PHP.
- Fibers: with the introduction of fibers in PHP 8.1, async code can be written in a more straightforward manner without diving deep into callbacks or promises. Fibers can interrupt their execution and return the control to the event loop.
Considerations and Best Practices 🤔
- Error handling: async code could make error handling a bit more challenging. You may want to write in more robust error handling mechanisms to deal with exceptions and rejections in promises.
- Testing: writing tests for async code will require different strategies. cspray.io is one of the tools you may wish to consider.
- Learning curve: whilst the benefits of async PHP code are enticing, there is a learning curve as with all things new and shiny. We’d recommend starting with smaller or more non-critical tasks to gain a foothold and better understanding.
- It’s not always the answer: Just because it’s new, just because it has a benefit, doesn’t mean it’s always best or right. It’s important that you assess your requirements and don’t just throw in new tech for new tech’s sake. Sometimes, a traditional synchronous approach might be simpler or more appropriate.
Code examples 👩💻
Enough talking and theory. Let’s look at some practical examples. Although we don’t champion any specific library, the examples we’ll use will use ReactPHP’s library.
Database queries ⌨️
Here’s a synchronous example I’m sure we’re all familiar with:
$pdo = new PDO($dsn, $username, $password);
$result = $pdo->query('SELECT * FROM users');
foreach ($result as $row) {
echo $row['name'];
}
Comparatively, here would be the asynchronous alternative:
$loop = React\EventLoop\Factory::create();
$factory = new React\MySQL\Factory($loop);
$connection = $factory->createLazyConnection($dsn);
$connection->query('SELECT * FROM users')->then(function ($command) {
foreach ($command->resultRows as $row) {
echo $row['name'];
}
});
$loop->run();
In asynchronous programming, the “loop” refers to the event loop. It’s the mechanism that facilitates non-blocking task execution. If you’ve used a queue system in a framework such as Laravel before, you’ll be pretty familiar with the process below.
The loop works like so:
- Initialisation: When your application starts it initialises the event loop. (So far, so good, right?)
- Polling: The loop continuously checks for tasks or events in its queue.
- Callback execution: If there’s a task in the queue and it’s ready to be executed (for example, a timer could have expired or an IO operation has completed), the associated callback will be executed.
- Wait & Continue: If there are no tasks in the queue or no tasks ready for execution, the loop simply will wait for new events or tasks. If a task arrives or an event is detected, it goes back to executing the associated callback.
Reading a file 📖
Super-simple. Here’s a synchronous code example:
$content = file_get_contents('file.txt');
echo $content;
echo "Done!";
Async isn’t much different, we just need it done within the loop:
$loop = React\EventLoop\Factory::create();
$filesystem = React\Filesystem\Filesystem::create($loop);
$file = $filesystem->file('file.txt');
$file->getContents()->then(function ($content) {
echo $content;
});
$loop->run();
echo "Done!";
The syntax is of course a touch different in the async example because it’s coming from a package and using its methods rather than those offered by core php.
Rounding off 🏁
The rise of async PHP demonstrates where the evolution of PHP as a language is going and its commitment to catering to modern web application requirements. Compare that to where it was 10 years ago? Huge difference in mindset and how its viewed in the world.
As with all things tech, tools and libraries will continually emerge to simplify async programming for the masses. PHP developers have so much more in their arsenal today to optimise performance and deliver outstanding user experiences that we ever did “back in our day”.
Whether you’re new to PHP or a seasoned developer, I think we can all agree that this is an exciting time to be working with it.
Time to Ascend 🚀
If you’re struggling with async PHP, or think that it may be something that could benefit your business, come talk to us.
We’re seasoned PHP experts with a proven track record in delivering industry redefining solutions using PHP with our framework of choice, Laravel. We can help you unlock your next level of potential today or support your development team in this exciting new transition.