Objetivo da configuração de ambiente
Em projetos back-end com Slim Framework, a configuração do ambiente define como o projeto nasce (Composer), como o código é carregado (autoload PSR-4), onde fica o ponto de entrada HTTP (front controller) e como separar configurações do código para facilitar manutenção, segurança e deploy. A ideia central é: o servidor web aponta para a pasta public/, o restante do código fica fora do alcance direto do navegador, e variáveis sensíveis ficam fora do repositório.
Criando o projeto do zero com Composer
Pré-requisitos
- PHP 8.1+ (recomendado 8.2+)
- Composer instalado
- Extensões comuns habilitadas:
json,mbstring
1) Inicialize o projeto
Crie uma pasta e inicialize o composer.json:
mkdir slim-app && cd slim-app
composer initDurante o assistente, defina um nome de pacote (ex.: acme/slim-app) e a licença conforme sua necessidade.
2) Instale o Slim e dependências úteis
Instale o Slim e uma implementação de PSR-7 (necessária para Request/Response). Um conjunto comum é:
composer require slim/slim:^4.0 slim/psr7:^1.6Para exibir erros em desenvolvimento, use o middleware oficial:
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
composer require slim/error-middleware:^1.0Para variáveis de ambiente via arquivo local (sem versionar segredos), use Dotenv:
composer require vlucas/phpdotenv:^5.6Estrutura de pastas recomendada
Uma estrutura simples, segura e fácil de evoluir:
slim-app/
app/
bootstrap.php
routes.php
settings.php
public/
index.php
src/
Http/
Controllers/
storage/
logs/
vendor/
.env
.env.example
.gitignore
composer.json
composer.lockpublic/: único diretório exposto ao servidor (document root).src/: código da aplicação (classes, controllers, serviços).app/: arquivos de configuração e bootstrap (sem lógica de domínio).storage/: arquivos gerados em runtime (logs, cache). Normalmente precisa de permissão de escrita.
Configurando autoload PSR-4 (Composer)
O PSR-4 permite que o Composer carregue classes automaticamente com base no namespace e caminho. Configure no composer.json:
{
"name": "acme/slim-app",
"require": {
"php": "^8.1",
"slim/slim": "^4.0",
"slim/psr7": "^1.6",
"slim/error-middleware": "^1.0",
"vlucas/phpdotenv": "^5.6"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}Depois, gere/atualize o autoload:
composer dump-autoloadExemplo de classe em src/Http/Controllers/HealthController.php:
<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
final class HealthController
{
public function __invoke(Request $request, Response $response): Response
{
$response->getBody()->write(json_encode(['status' => 'ok'], JSON_THROW_ON_ERROR));
return $response->withHeader('Content-Type', 'application/json');
}
}Separando configurações do código
Evite “espalhar” configurações em controllers e rotas. Centralize em arquivos dedicados e carregue no bootstrap. Um arranjo prático:
app/settings.php: lê variáveis de ambiente e define settings.app/bootstrap.php: cria o App, registra middlewares e rotas.app/routes.php: define rotas.
Arquivo .env e .env.example
Crie um .env local (não versionado) e um .env.example (versionado) para documentar as chaves necessárias.
.env (local):
APP_ENV=dev
APP_DEBUG=true
APP_BASE_PATH=
.env.example (repositório):
APP_ENV=dev
APP_DEBUG=true
APP_BASE_PATH=
Em produção, normalmente você não usa .env no servidor; define variáveis no ambiente do sistema/serviço.
app/settings.php
Centralize o que muda por ambiente (debug, base path, etc.). Exemplo:
<?php
declare(strict_types=1);
return function (): array {
$env = $_ENV['APP_ENV'] ?? 'prod';
$debug = filter_var($_ENV['APP_DEBUG'] ?? 'false', FILTER_VALIDATE_BOOLEAN);
$basePath = $_ENV['APP_BASE_PATH'] ?? '';
return [
'env' => $env,
'debug' => $debug,
'base_path' => $basePath,
];
};Ponto de entrada: organizando o public/index.php
O public/index.php deve ser pequeno: carregar autoload, carregar variáveis de ambiente, chamar o bootstrap e rodar a aplicação. Exemplo:
<?php
declare(strict_types=1);
use Dotenv\Dotenv;
require __DIR__ . '/../vendor/autoload.php';
// Carrega variáveis de ambiente (somente se existir arquivo .env)
$dotenvPath = dirname(__DIR__);
if (file_exists($dotenvPath . '/.env')) {
Dotenv::createImmutable($dotenvPath)->safeLoad();
}
$app = (require __DIR__ . '/../app/bootstrap.php')();
$app->run();Boa prática: evite colocar rotas e configurações diretamente no index.php. Isso facilita testes e reaproveitamento.
Bootstrap da aplicação
O bootstrap cria a instância do Slim, aplica configurações, registra middlewares e rotas. Exemplo de app/bootstrap.php:
<?php
declare(strict_types=1);
use Slim\Factory\AppFactory;
use Slim\Middleware\ErrorMiddleware;
return function () {
$settings = (require __DIR__ . '/settings.php')();
$app = AppFactory::create();
// Base path (útil quando o app não está na raiz do domínio)
if (!empty($settings['base_path'])) {
$app->setBasePath($settings['base_path']);
}
// Error middleware: exibir detalhes apenas em desenvolvimento
$displayErrorDetails = ($settings['env'] === 'dev') && ($settings['debug'] === true);
$logErrors = true;
$logErrorDetails = ($settings['env'] === 'dev');
$errorMiddleware = new ErrorMiddleware(
$app->getCallableResolver(),
$app->getResponseFactory(),
$displayErrorDetails,
$logErrors,
$logErrorDetails
);
$app->add($errorMiddleware);
// Rotas
(require __DIR__ . '/routes.php')($app);
return $app;
};Rotas em arquivo separado: app/routes.php
<?php
declare(strict_types=1);
use Slim\App;
use App\Http\Controllers\HealthController;
return function (App $app): void {
$app->get('/health', HealthController::class);
};Para que HealthController::class funcione como callable, você pode instanciar manualmente, ou integrar um container. Sem container, faça:
$app->get('/health', new HealthController());Se você optar por container depois, o arquivo de rotas permanece limpo e a mudança fica concentrada no bootstrap.
Servidor local com PHP built-in server
Para desenvolvimento, o servidor embutido do PHP é suficiente. Aponte o document root para public/:
php -S localhost:8080 -t publicAcesse:
http://localhost:8080/healthRoteamento para front controller (quando necessário)
Em alguns cenários, o built-in server pode precisar de um script de roteamento para servir arquivos estáticos e redirecionar o restante para o index.php. Crie public/router.php:
<?php
declare(strict_types=1);
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$file = __DIR__ . $path;
if ($path !== '/' && file_exists($file) && !is_dir($file)) {
return false; // serve o arquivo diretamente
}
require __DIR__ . '/index.php';Rode assim:
php -S localhost:8080 -t public public/router.phpBoas práticas de caminhos e permissões
Document root sempre em public/
Mantenha vendor/, src/ e app/ fora do alcance do navegador. Em servidores como Nginx/Apache, configure o root para public/. Em desenvolvimento, use -t public.
Permissões mínimas necessárias
Evite dar permissão de escrita para todo o projeto. Em geral, apenas storage/ precisa ser gravável pelo usuário do servidor. Exemplo (Linux):
mkdir -p storage/logs
chmod -R 775 storage
Se estiver em ambiente compartilhado, ajuste o grupo/usuário conforme o processo do PHP/servidor web. Evite chmod 777 como prática padrão.
Construção de caminhos com __DIR__ e dirname()
Para evitar problemas de caminho relativo, sempre monte paths a partir de diretórios conhecidos:
$root = dirname(__DIR__); // a partir de public/
$settingsFile = $root . '/app/settings.php';Exibição de erros apenas em desenvolvimento
O objetivo é: em desenvolvimento, ver stack trace e detalhes; em produção, retornar respostas genéricas e registrar logs sem expor informações internas.
No exemplo do app/bootstrap.php, isso é controlado por:
APP_ENV=deveAPP_DEBUG=truepara habilitar$displayErrorDetails.- Em produção:
APP_ENV=prodeAPP_DEBUG=false.
Recomendação prática de valores:
| Ambiente | APP_ENV | APP_DEBUG | displayErrorDetails |
|---|---|---|---|
| Desenvolvimento | dev | true | true |
| Produção | prod | false | false |
Variáveis sensíveis fora do repositório
.gitignore essencial
Garanta que .env e diretórios gerados não sejam versionados:
/vendor/
/.env
/storage/logs/
O que nunca versionar
- Senhas e tokens (DB, JWT secret, API keys)
- Arquivos de credenciais
- Chaves privadas
Como documentar sem expor segredos
Use .env.example com valores fictícios e descreva o significado das chaves em comentários, por exemplo:
APP_ENV=dev
APP_DEBUG=true
# APP_BASE_PATH=/minha-app (use quando publicar em subdiretório)
APP_BASE_PATH=
Em produção, defina as variáveis no ambiente do servidor (systemd, Docker, painel de hospedagem, etc.) e mantenha o repositório livre de segredos.