Capítulo 01: Ecossistema Laravel 11, Composer, Artisan CLI e Ciclo de Vida
Especialização em Backend com PHP & Laravel • Laravel 11 & PHP 8.3+ • Eloquent ORM, Sanctum, Filas, Horizon e APIs Corporativas
🗺️ Mapa Conceitual do Tópico
flowchart TD
A["Requisição HTTP"] --> B["public/index.php"]
B --> C["Bootstrap do Kernel HTTP"]
C --> D["Service Providers (register)"]
D --> E["Service Providers (boot)"]
E --> F["Service Container resolve dependências"]
F --> G["Router despacha para Controller"]
G --> H["Resposta HTTP"]
subgraph CLI["Ferramentas de Apoio"]
I["Composer: autoload e dependências"]
J["Artisan: comandos, cache, geração de código"]
end
D -.-> CLI
style A fill:#e1f5fe,stroke:#03a9f4,stroke-width:2px
style B fill:#fff3e0,stroke:#ff9800,stroke-width:2px
style C fill:#ede7f6,stroke:#7e57c2,stroke-width:2px
style D fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
style E fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
style F fill:#fce4ec,stroke:#e91e63,stroke-width:2px
style G fill:#f3e5f5,stroke:#9c27b0,stroke-width:2px
🏛️ 1. O Ciclo de Vida de uma Requisição Laravel
Toda requisição HTTP que chega a uma aplicação Laravel passa por public/index.php, que carrega o autoload do Composer e instancia a aplicação a partir de bootstrap/app.php. A partir daí, o Kernel HTTP entra em ação e percorre duas fases fundamentais em todo Service Provider registrado em bootstrap/providers.php (ou config/app.php em versões anteriores):
register()— fase em que cada provider deve apenas declarar bindings no Service Container. Nenhuma dependência de outro provider pode ser resolvida aqui, pois a ordem de registro não é garantida.boot()— executada somente depois que todos os providers já registraram seus bindings. É seguro resolver dependências de outros providers dentro deboot().
Esse ciclo de duas fases existe porque o Service Container (o mecanismo de Injeção de Dependência do Laravel) precisa que todos os “contratos” (interfaces) estejam mapeados para suas implementações concretas antes que qualquer código tente resolvê-los.
Composer vs. Artisan
- Composer é o gerenciador de dependências PHP: resolve
composer.json, baixa pacotes emvendor/e gera o autoloader PSR-4 (vendor/autoload.php), que é o primeiro arquivo carregado porindex.php. - Artisan é a CLI própria do Laravel (
php artisan), construída sobre o Symfony Console. Ela expõe comandos nativos (migrate,make:model,queue:work) e permite criar comandos customizados viaphp artisan make:command.
🧩 2. Service Container e Service Providers na Prática
O binding mais comum é o de interface para implementação concreta, permitindo trocar a implementação real (ex.: gateway de pagamento) sem alterar o código que a consome:
<?php
// app/Providers/PaymentServiceProvider.php
namespace App\Providers;
use App\Contracts\PaymentGatewayInterface;
use App\Services\StripePaymentGateway;
use Illuminate\Support\ServiceProvider;
class PaymentServiceProvider extends ServiceProvider
{
public function register(): void
{
// Singleton: a mesma instância é reaproveitada durante toda a requisição.
$this->app->singleton(PaymentGatewayInterface::class, StripePaymentGateway::class);
}
public function boot(): void
{
// Aqui já é seguro resolver outros bindings, publicar configs, registrar rotas, etc.
}
}
Qualquer classe que declare PaymentGatewayInterface no construtor recebe automaticamente uma instância de StripePaymentGateway, resolvida via autowiring (reflexão de tipos) — a base de como controllers, jobs e form requests recebem suas dependências sem código de fábrica manual.
⚙️ 3. Configuração: env() vs. config()
Um erro comum de iniciantes é chamar env('STRIPE_SECRET') diretamente em controllers ou services. Isso quebra em produção assim que php artisan config:cache é executado: o comando serializa todos os arquivos de config/*.php em um único cache e, a partir daí, env() fora desses arquivos retorna sempre null, porque o .env deixa de ser lido em runtime.
A prática correta é: env() só dentro de config/*.php, e config('chave') em todo o resto do código.
<?php
// config/services.php
return [
'stripe' => [
'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET'),
],
];
// Em qualquer Controller/Service:
$secret = config('services.stripe.secret'); // ✅ funciona mesmo com config cacheado
🚀 4. Artisan para Produtividade e Performance
Comandos customizados seguem uma assinatura declarativa ($signature) que já cuida de parsing de argumentos e opções:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
class CleanTempCommand extends Command
{
protected $signature = 'app:clean-temp {--days=7 : Dias de retenção}';
protected $description = 'Remove arquivos temporários mais antigos que N dias';
public function handle(): int
{
$dias = (int) $this->option('days');
$this->info("Limpando arquivos com mais de {$dias} dias...");
// ... lógica de remoção ...
return Command::SUCCESS;
}
}
Para deploy em produção, quatro comandos de cache reduzem drasticamente a latência de bootstrap, pois evitam reprocessar arquivos PHP, resolver rotas e recompilar views a cada requisição:
php artisan config:cache # serializa config/*.php
php artisan route:cache # serializa as rotas (exige rotas sem closures)
php artisan view:cache # pré-compila as views Blade
php artisan event:cache # serializa o mapeamento de eventos/listeners
Também é possível publicar arquivos de configuração de pacotes de terceiros da pasta vendor/ para config/ com php artisan vendor:publish --tag=nome-da-tag — nunca editando vendor/ diretamente, pois qualquer composer update sobrescreveria as alterações.