Posted on: January 27, 2026 08:38 PM
Posted by: Renato
Categories: PHP PHP Swoole phpswoole Hyperf Docker
Views: 411
Introdução ao Hyperf para PHP
O que é hyperf ? Hyperf para o PHP? Framework e como usar?
Se você vem do mundo PHP tradicional (como Laravel ou Symfony rodando em Apache/Nginx), o Hyperf vai parecer um salto para o futuro.
Em resumo: o Hyperf é um framework PHP de alta performance e nativo para a nuvem, focado em microserviços e persistência de memória.
O que torna o Hyperf diferente?
A maioria dos frameworks PHP segue o modelo "share-nothing": a cada requisição, o PHP inicia do zero e morre ao terminar. O Hyperf utiliza o Swoole ou o Swow, que são extensões que permitem ao PHP rodar em corrotinas.
Isso significa que o PHP passa a funcionar de forma semelhante ao Node.js ou Go: o servidor sobe uma vez, mantém as conexões abertas e gerencia múltiplas tarefas simultaneamente sem travar o processo principal.
Principais Características
-
Velocidade Extrema: Milhares de requisições por segundo com baixíssimo consumo de CPU.
-
Injeção de Dependência (DI): Um sistema de DI extremamente robusto com suporte a anotações/atributos.
-
AOP (Programação Orientada a Aspectos): Permite "interceptar" métodos sem alterar o código original (ideal para logs ou cache).
-
Cloud Native: Já vem com componentes prontos para Service Discovery, Circuit Breaker e gRPC.
Como ele se compara ao Laravel?
| Característica | Laravel (Tradicional) | Hyperf |
| Servidor | Nginx + PHP-FPM | Swoole / Swow (Standalone) |
| Estado | Stateless (reinicia sempre) | Stateful (mantém dados na memória) |
| I/O | Bloqueante | Não-bloqueante (Corrotinas) |
| Curva de Aprendizado | Baixa/Média | Média/Alta |
Como usar (Primeiros Passos)
Para rodar o Hyperf, você precisa da extensão Swoole instalada no seu ambiente PHP ou, o que é mais comum e recomendado, usar Docker.
1. Instalação via Composer
Você pode criar um projeto novo usando o esqueleto oficial:
Bash
composer create-project hyperf/hyperf-skeleton
Durante a instalação, o terminal perguntará quais componentes você deseja incluir (Redis, Database, etc.). O Hyperf é modular: você só instala o que vai usar.
2. Estrutura de um Controller
A sintaxe será familiar se você conhece o ecossistema moderno do PHP, mas com o uso intenso de Attributes:
PHP
namespace App\Controller;
use Hyperf\HttpServer\Annotation\AutoController;
#[AutoController]
class IndexController
{
public function index()
{
return [
'mensagem' => 'Olá, Hyperf!',
];
}
}
3. Iniciando o Servidor
Diferente do php artisan serve, aqui você inicia o servidor de corrotinas:
Bash
php bin/hyperf.php start
Quando escolher o Hyperf?
-
Se você precisa construir Microserviços que escalam horizontalmente.
-
Se sua aplicação lida com WebSockets ou conexões de longa duração.
-
Se o custo de infraestrutura do PHP-FPM está ficando alto demais para o seu volume de tráfego.
Cuidado: Como o Hyperf mantém a aplicação na memória, erros de "memory leak" ou variáveis globais mal geridas podem derrubar o serviço. É uma ferramenta poderosa, mas exige mais atenção ao ciclo de vida das variáveis.
Para rodar o Hyperf de forma otimizada, o ideal é usar uma imagem base que já contenha o Swoole (ou Swow) pré-instalado. A equipe oficial do Hyperf mantém imagens excelentes no Docker Hub.
Aqui está uma configuração profissional, focada em performance e pronta para desenvolvimento:
1. Dockerfile (Otimizado)
Este Dockerfile utiliza uma abordagem de estágio único para simplicidade, mas foca em configurações recomendadas para o ambiente de execução do Hyperf.
Dockerfile
# Usamos a imagem oficial do Hyperf que já vem com PHP 8.1/8.2 e Swoole
FROM hyperf/hyperf:8.2-alpine-v3.18-swoole
LABEL maintainer="Hyperf Developer <[email protected]>" version="1.0"
##
# Instalação de dependências extras (se necessário)
# O Alpine é muito leve, então adicionamos apenas o essencial
##
RUN apk update && apk add --no-cache \
libstdc++ \
openssl \
php82-pear \
php82-dev \
gcc \
g++ \
make
# Configuração do diretório de trabalho
WORKDIR /opt/www
# Copiamos o composer.json primeiro para aproveitar o cache das camadas do Docker
COPY composer.json /opt/www/composer.json
COPY composer.lock /opt/www/composer.lock
# Instalação das dependências do Composer
RUN composer install --no-dev --no-scripts --optimize-autoloader
# Copiamos o restante do código
COPY . /opt/www
# Expomos a porta padrão do Hyperf
EXPOSE 9501
# Configurações de performance do PHP (Opcional, mas recomendado)
RUN ln -sf /usr/bin/php82 /usr/bin/php
# Comando para iniciar o servidor
# No Hyperf, usamos o script bin/hyperf.php
ENTRYPOINT ["php", "/opt/www/bin/hyperf.php", "start"]
2. docker-compose.yml (Hyperf + MySQL 8)
Este arquivo configura o ambiente completo. Note que incluí um network para garantir que o Hyperf consiga se comunicar com o MySQL pelo nome do serviço.
YAML
version: '3.8'
services:
# Serviço do Hyperf
app:
build:
context: .
dockerfile: Dockerfile
container_name: hyperf_app
ports:
- "9501:9501"
volumes:
- .:/opt/www # Monta o código atual para hot-reload em dev
networks:
- hyperf_net
depends_on:
- mysql
environment:
- DB_HOST=mysql
- DB_PORT=3306
- DB_DATABASE=hyperf_db
- DB_USERNAME=root
- DB_PASSWORD=root_password
# Serviço do MySQL
mysql:
image: mysql:8.0
container_name: hyperf_mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: hyperf_db
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
networks:
- hyperf_net
networks:
hyperf_net:
driver: bridge
volumes:
mysql_data:
Como usar:
-
Configuração do
Snippet de código.env: No seu projeto Hyperf, certifique-se de que as variáveis de banco de dados no arquivo.envapontem para o hostmysql(o nome do serviço no docker-compose):DB_HOST=mysql DB_PORT=3306 DB_DATABASE=hyperf_db DB_USERNAME=root DB_PASSWORD=root_password -
Subir os containers:
Bashdocker-compose up -d -
Acessar a aplicação: A aplicação estará rodando em
http://localhost:9501.
Dicas de Otimização:
-
Scan de Anotações: O Hyperf gera um cache de anotações no diretório
runtime/. No Docker de produção, certifique-se de gerar esse cache durante o build para que a inicialização seja instantânea. -
Hot Reload: Para desenvolvimento, você pode usar o componente
hyperf/watcher. Com ele, o container reinicia automaticamente ao detectar mudanças no código PHP. -
Privilégios: Em produção, evite rodar o container como
root. Adicione um usuário específico no Dockerfile.
JSON Web Tokens + hyperf
Essa é uma excelente implementação básica utilizando a biblioteca firebase/php-jwt.
1. Dependências Necessárias
Certifique-se de ter as bibliotecas instaladas no seu container:
Bash
composer require firebase/php-jwt ramsey/uuid
2. Controller Refatorado (Otimizado para Hyperf)
No Hyperf, os Controllers são Singletons por padrão. O uso de env() dentro do construtor é possível, mas injetar a Request e Response diretamente em propriedades da classe pode causar problemas de "vazamento" de dados entre requisições em ambientes de corrotinas. O ideal é recebê-las nos métodos ou usar o Context.
PHP
namespace App\Controller;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Ramsey\Uuid\Uuid;
use function Hyperf\Support\env;
class ControllerJWT
{
protected string $jwtKey;
public function __construct()
{
// Pegando a chave do .env ou usando uma fallback
$this->jwtKey = env('JWT_SECRET', 'sua_chave_super_secreta_123');
}
public function generate(ResponseInterface $response)
{
$payload = [
'iss' => 'hyperf-app', // Emissor
'iat' => time(), // Gerado em
'exp' => time() + 3600, // Expira em 1 hora
'uuid' => Uuid::uuid4()->toString(),
'data' => bin2hex(random_bytes(16))
];
$token = JWT::encode($payload, $this->jwtKey, 'HS256');
return [
'status' => 'success',
'token' => $token,
'expires_in' => 3600
];
}
public function decode(RequestInterface $request, ResponseInterface $response)
{
// Captura o Header Authorization
$authHeader = $request->getHeaderLine('Authorization');
$token = str_replace('Bearer ', '', $authHeader);
if (!$token) {
return $response->json(['error' => 'Token not provided'])->withStatus(401);
}
try {
// Decodificação usando a Key object (exigência das versões recentes do firebase/php-jwt)
$decoded = JWT::decode($token, new Key($this->jwtKey, 'HS256'));
return [
'status' => 'valid',
'data' => $decoded
];
} catch (\Exception $e) {
return $response->json([
'error' => 'Invalid or expired token',
'message' => $e->getMessage()
])->withStatus(401);
}
}
}
3. Configuração de Rotas (config/routes.php)
Se você não usar a anotação #[AutoController], defina manualmente:
PHP
use Hyperf\HttpServer\Router\Router;
Router::addRoute(['GET', 'POST'], '/generate', 'App\Controller\ControllerJWT@generate');
Router::addRoute(['GET', 'POST'], '/decode', 'App\Controller\ControllerJWT@decode');
Dicas de "Pulo do Gato" para Hyperf:
-
Segurança de Corrotina: Note que eu passei
RequestInterface $requestdiretamente nos argumentos do método. Isso garante que o Hyperf injete a instância correta da requisição atual daquela corrotina específica. -
Middleware: Em um projeto real, você não faria o
decodedentro do Controller. Você criaria um Middleware para proteger as rotas. Assim, o Controller só seria executado se o token fosse válido. -
Configuração: Em vez de
env()direto no Controller, o padrão do Hyperf é criar um arquivo emconfig/autoload/jwt.phpe usar oConfigInterfacepara ler os dados.
Transformar a validação em um Middleware é a forma correta de trabalhar no Hyperf. Isso mantém seu Controller "limpo", focado apenas na lógica de negócio, enquanto o Middleware cuida da segurança.
1. Criando o Middleware
No Hyperf, o Middleware intercepta a requisição antes de ela chegar ao Controller. Se o token for inválido, nós barramos a requisição ali mesmo.
Execute o comando para gerar a classe: php bin/hyperf.php gen:middleware JwtAuthMiddleware
Depois, edite o arquivo em app/Middleware/JwtAuthMiddleware.php:
PHP
namespace App\Middleware;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface;
use Hyperf\Context\Context;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Psr\Http\Message\ResponseInterface as PsrResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class JwtAuthMiddleware implements MiddlewareInterface
{
protected string $jwtKey;
public function __construct(protected ResponseInterface $response, protected RequestInterface $request)
{
$this->jwtKey = (string) env('JWT_SECRET', 'sua_chave_super_secreta_123');
}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): PsrResponseInterface
{
$authHeader = $request->getHeaderLine('Authorization');
$token = str_replace('Bearer ', '', $authHeader);
if (!$token) {
return $this->response->json(['error' => 'Token não fornecido'])->withStatus(401);
}
try {
$decoded = JWT::decode($token, new Key($this->jwtKey, 'HS256'));
// "Pulo do gato": Salva os dados do token no Contexto da Corrotina
// Assim, qualquer Controller pode acessar os dados do usuário logado
$request = $request->withAttribute('user_data', (array) $decoded);
Context::set(ServerRequestInterface::class, $request);
return $handler->handle($request);
} catch (\Exception $e) {
return $this->response->json(['error' => 'Token inválido ou expirado'])->withStatus(401);
}
}
}
2. Registrando o Middleware em config/autoload/middlewares.php
Você pode aplicar o middleware de forma global (em todas as rotas) ou apenas em um grupo específico. Geralmente, usamos em grupos:
PHP
return [
'http' => [
// Middlewares globais aqui
],
];
Ou diretamente no arquivo de rotas (routes.php), o que é mais comum para APIs:
PHP
use App\Middleware\JwtAuthMiddleware;
use Hyperf\HttpServer\Router\Router;
// Rota pública para gerar o token
Router::addRoute(['GET', 'POST'], '/generate', 'App\Controller\ControllerJWT@generate');
// Grupo de rotas protegidas pelo JWT
Router::addGroup('/v1', function () {
Router::addRoute(['GET'], '/perfil', 'App\Controller\UserController@me');
Router::addRoute(['GET'], '/decode', 'App\Controller\ControllerJWT@decode');
}, ['middleware' => [JwtAuthMiddleware::class]]);
3. Como acessar os dados no Controller agora?
Agora seu método decode ou qualquer outra rota protegida fica muito mais simples, pois o Middleware já fez o trabalho pesado:
PHP
public function me(RequestInterface $request)
{
// Recupera os dados que o Middleware injetou no atributo da requisição
$userData = $request->getAttribute('user_data');
return [
'mensagem' => 'Acesso autorizado!',
'user' => $userData
];
}
Por que isso é melhor?
-
Reutilização: Você protege 10 ou 100 rotas apenas adicionando-as ao grupo no arquivo de rotas.
-
Organização: O Controller não precisa saber como o token é validado, ele apenas recebe os dados prontos.
-
Performance: O Hyperf gerencia o Middleware de forma extremamente eficiente dentro do ciclo de vida das corrotinas.
- Fonte:
https://github.com/hyperf/hyperf
https://github.com/thiagoeti/php-hyperf-firebase-jwt
https://www.linkedin.com/feed/update/urn:li:activity:7421928265054945280/
Donate to Site
Renato
Developer