Programação Assíncrona em PHP: Guia Completo para Iniciantes

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução à Programação Assíncrona em PHP

\n\n

O PHP tradicional funciona de forma síncrona: cada operação é executada sequencialmente. Se um script precisa enviar uma requisição HTTP ou ler um arquivo, ele espera a conclusão da operação, bloqueando a execução de todo o código. Para aplicações web de alta carga, isso se torna um gargalo. A programação assíncrona resolve esse problema, permitindo executar várias tarefas simultaneamente sem bloquear o fluxo principal.

\n\n

Neste guia, vamos analisar como a assincronia funciona em PHP, quais ferramentas estão disponíveis e como usá-las na prática. Você aprenderá sobre generators, bibliotecas ReactPHP e Swoole, além dos novos recursos do PHP 8.1 — Fiber.

\n\n

Fundamentos da Programação Assíncrona

\n\n

O que é assincronia e por que ela é necessária?

\n\n

Imagine que você está preparando o café da manhã. Abordagem síncrona: você coloca a chaleira no fogo, espera ferver, depois começa a fritar os ovos. Abordagem assíncrona: você coloca a chaleira e, enquanto a água aquece, prepara os ovos paralelamente. Em PHP, isso significa que, em vez de esperar a resposta de um banco de dados ou API externa, você pode executar outro código.

\n\n

Principais vantagens da abordagem assíncrona:

\n
    \n
  • Aumento de desempenho em operações de I/O (rede, discos, bancos de dados)
  • \n
  • Economia de recursos do servidor — menos threads processam mais requisições
  • \n
  • Possibilidade de criar aplicações em tempo real (chats, notificações, streaming)
  • \n
\n\n

O problema do código síncrono

\n\n

Considere um exemplo clássico: obter dados de duas APIs remotas. O código síncrono será executado sequencialmente:

\n\n
<?php\nfunction fetchData($url) {\n    $ch = curl_init($url);\n    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n    $result = curl_exec($ch); // Bloqueio durante a requisição\n    curl_close($ch);\n    return $result;\n}\n\n$start = microtime(true);\n$data1 = fetchData('https://api.example.com/users');\n$data2 = fetchData('https://api.example.com/posts');\necho "Tempo: " . (microtime(true) - $start);\n?>
\n\n

Se cada requisição leva 2 segundos, o tempo total de execução será de 4 segundos, embora pudéssemos executar as requisições em paralelo.

\n\n

Ferramentas para Assincronia em PHP

\n\n

1. Generators (yield) — Assincronia Leve

\n\n

Generators surgiram no PHP 5.5 e permitem criar funções que podem pausar sua execução e retornar o controle ao código chamador. Esta é a base para criar coroutines.

\n\n
<?php\nfunction generator() {\n    echo "Início do generator\\n";\n    yield 1;\n    echo "Após o primeiro yield\\n";\n    yield 2;\n    echo "Fim\\n";\n}\n\n$gen = generator();\nforeach ($gen as $value) {\n    echo "Recebido: $value\\n";\n}\n?>
\n\n

Generators podem ser usados para organizar operações não bloqueantes em conjunto com um event loop. No entanto, para assincronia completa, isso não é suficiente — é necessária uma biblioteca.

\n\n

2. ReactPHP — Biblioteca Orientada a Eventos

\n\n

ReactPHP é uma biblioteca popular para programação assíncrona. Ela fornece um event loop, sockets não bloqueantes, cliente e servidor HTTP. Instalação via Composer:

\n\n
composer require react/event-loop react/http
\n\n

Exemplo de requisição HTTP assíncrona:

\n\n
<?php\nrequire 'vendor/autoload.php';\n\nuse React\\EventLoop\\Factory;\nuse React\\HttpClient\\Client;\nuse React\\HttpClient\\Response;\n\n$loop = Factory::create();\n$client = new Client($loop);\n\n$request = $client->request('GET', 'https://api.example.com/data');\n$request->on('response', function (Response $response) {\n    $response->on('data', function ($chunk) {\n        echo "Fragmento recebido: " . strlen($chunk) . " bytes\\n";\n    });\n    $response->on('end', function () {\n        echo "Requisição concluída\\n";\n    });\n});\n$request->end();\n\necho "Requisição enviada, aguardando...\\n";\n$loop->run();\n?                

Blogs

Book Recommendations