Dependências Externas
Declare bibliotecas externas no composer.json do seu módulo. A IDE instala tudo automaticamente no deploy.
Como funciona
Cada módulo criado na IDE já vem com um composer.json próprio. Você declara as dependências que precisa — como PHPMailer, Guzzle, Stripe SDK — e ao clicar em Publicar, o sistema:
Verifica conflitos
Compara as versões requeridas com o composer.lock do projeto usando Composer\Semver. Se houver conflito, o deploy é bloqueado com erro claro antes de qualquer mudança.
Instala apenas o que falta
Pacotes já instalados e compatíveis são ignorados — zero efeito colateral. Apenas pacotes novos são instalados via composer require.
Registra o namespace
O namespace PSR-4 do módulo é adicionado ao composer.json do projeto e o autoloader é regenerado.
Recarrega o PHP-FPM
O OPcache é invalidado e o PHP-FPM recarregado graciosamente. As classes ficam disponíveis imediatamente na próxima requisição.
Exemplo: módulo com PHPMailer
Edite o composer.json do seu módulo na IDE e declare a dependência:
{
"name": "meu-vendor/modulo-notificacao",
"description": "Módulo de notificações por e-mail",
"require": {
"php": ">=8.1",
"phpmailer/phpmailer": "^6.9"
},
"autoload": {
"psr-4": {
"Src\\Modules\\Notificacao\\": ""
}
},
"extra": {
"vupi.us": {
"provides": ["email-sender"]
}
}
}
No seu Service, use normalmente:
<?php
namespace Src\Modules\Notificacao\Services;
use PHPMailer\PHPMailer\PHPMailer;
class NotificacaoService
{
public function enviar(string $para, string $assunto, string $html): void
{
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = $_ENV['MAILER_HOST'];
$mail->Username = $_ENV['MAILER_USERNAME'];
$mail->Password = $_ENV['MAILER_PASSWORD'];
$mail->Port = (int) $_ENV['MAILER_PORT'];
$mail->SMTPAuth = true;
$mail->setFrom($_ENV['MAILER_FROM_EMAIL'], $_ENV['MAILER_FROM_NAME']);
$mail->addAddress($para);
$mail->isHTML(true);
$mail->Subject = $assunto;
$mail->Body = $html;
$mail->send();
}
}
O projeto já inclui phpmailer/phpmailer, firebase/php-jwt, ramsey/uuid e vlucas/phpdotenv. Reutilize-as sempre que possível para evitar conflitos de versão.
Dependency Health Report e botão de instalação
O painel lateral da IDE exibe automaticamente o status de saúde das dependências do módulo aberto. Quando há pacotes ausentes, aparece o botão "Instalar dependências" — sem precisar fazer deploy:
🟢 OK
Tudo instalado e compatível. Pode publicar.
🟡 Warning + botão
Pacote ausente. O botão "Instalar dependências" aparece. Clique para instalar sem precisar fazer deploy.
🔴 Critical
Conflito de versão. Deploy bloqueado. A IDE mostra versão instalada, requerida e sugestão de fix.
Como instalar dependências na IDE
Edite o composer.json
Abra composer.json na IDE e adicione o pacote na seção require. Salve com Ctrl+S.
Veja o status no painel
O painel lateral atualiza automaticamente. O pacote aparece com status 🟡 não instalado e o botão "Instalar dependências" aparece.
Clique em "Instalar dependências"
O sistema roda composer require em background. Ao terminar, o status muda para 🟢 e a lib fica disponível no terminal e no código.
Use no terminal para testar
Abra o terminal da IDE (Ctrl+`) e teste a lib diretamente: $mail = new PHPMailer\PHPMailer\PHPMailer();
O que acontece quando algo dá errado
| Situação | O que a IDE mostra | O que fazer |
|---|---|---|
| Pacote não existe no Packagist | Modal com: "Pacote(s) não encontrado(s): vendor/pacote — verifique o nome em packagist.org" | Corrija o nome no composer.json. Formato: vendor/pacote |
| Versão incompatível com o PHP do servidor | Modal com: "Versão incompatível com o PHP atual do servidor" | Use uma versão mais antiga do pacote que suporte seu PHP |
| Conflito com pacote já instalado | Modal com lista de conflitos, versão instalada, requerida e sugestão | Use constraint flexível: "^7.0 || ^6.5" |
| Sem conexão com a internet | Modal com: "Sem conexão com o Packagist" | Verifique a conexão do servidor |
| Módulo não publicado ainda | Erro: "O módulo ainda não foi publicado. Clique em Publicar primeiro." | Publique o módulo antes de instalar dependências separadamente |
Resolvendo conflitos de versão
Quando o deploy é bloqueado por conflito, a IDE exibe um modal com os detalhes e a sugestão automática:
Conflito de dependências detectado 🚫
📦 guzzlehttp/guzzle
Instalado: 7.8.1
Requerido: ^6.0
💡 Sugestão: ^7.0 || ^6.0
Ajuste a constraint no composer.json do módulo:
"require": {
"guzzlehttp/guzzle": "^7.0 || ^6.0"
}
Recursos do sistema disponíveis no seu módulo
Antes de adicionar dependências externas, verifique o que o kernel já oferece gratuitamente via injeção de dependência:
| Interface / Classe | O que faz | Como usar no construtor |
|---|---|---|
EmailSenderInterface |
Envia e-mails via SMTP (PHPMailer já configurado) | private ?EmailSenderInterface $email = null |
UserRepositoryInterface |
Busca usuários por UUID, e-mail ou username | private UserRepositoryInterface $usuarios |
TokenBlacklistInterface |
Verifica se um JWT foi revogado | private TokenBlacklistInterface $blacklist |
PDO |
Conexão com o banco de dados (core ou modules) | private PDO $pdo |
AuditLogger |
Registra eventos de segurança no banco e stderr | private AuditLogger $audit |
ThreatScorer |
Acumula score de comportamento suspeito por IP | private ThreatScorer $threat |
IdempotencyLock |
Distributed lock para operações críticas (evita race condition) | Uso estático: IdempotencyLock::acquire('chave', 30) |
IpResolver |
Resolve IP real do cliente (respeita TRUST_PROXY) | Uso estático: IpResolver::resolve() |
Sanitizer |
Sanitiza inputs: string, email, uuid, url, search... | Uso estático: Sanitizer::string($input) |
OwnershipGuard |
Verifica se o usuário autenticado é dono do recurso (previne IDOR) | Uso estático: OwnershipGuard::check($userId, $resourceOwnerId) |
RelogioTimeZone |
Retorna DateTimeImmutable com timezone do APP_TIMEZONE | Uso estático: RelogioTimeZone::agora() |
ImageProcessor |
Redimensiona e salva imagens (JPEG, PNG, WebP) | private ImageProcessor $images |
Exemplo usando EmailSenderInterface e AuditLogger juntos:
<?php
namespace Src\Modules\Pedido\Services;
use Src\Kernel\Contracts\EmailSenderInterface;
use Src\Kernel\Support\AuditLogger;
use Src\Kernel\Http\Request\Request;
class PedidoService
{
public function __construct(
private readonly PedidoRepository $repository,
private readonly ?EmailSenderInterface $email = null, // opcional
private readonly ?AuditLogger $audit = null // opcional
) {}
public function criar(array $data, Request $request): array
{
$pedido = $this->repository->create($data);
// Envia e-mail de confirmação (se módulo de e-mail instalado)
$this->email?->sendCustom(
$data['email'],
'Pedido confirmado',
"<p>Pedido #{$pedido['id']} criado!</p>"
);
// Registra no audit log
$this->audit?->registrar('pedido.criado', $data['user_id'], [
'pedido_id' => $pedido['id'],
]);
return $pedido;
}
}
Boas práticas
| Regra | Exemplo |
|---|---|
| ✅ Use o que o kernel já oferece | EmailSenderInterface, AuditLogger, Sanitizer |
| ✅ Constraints flexíveis | "^7.0 || ^6.5" |
| ⚠️ Evite novas dependências desnecessárias | Implemente funções simples diretamente |
| ❌ Nunca fixe versões rígidas | "guzzle": "7.8.1" → use "^7.0" |
Após instalar uma dependência, abra o terminal (Ctrl+`) e teste diretamente. O sandbox carrega o vendor/autoload.php do projeto, então todas as libs instaladas ficam disponíveis imediatamente — sem precisar fazer deploy.