Template base para aplicacoes web em PHP com arquitetura orientada a rotas e controllers, utilizando Slim 4 como microframework HTTP/PSR-7 e Twig como engine de templates para composicao da camada de apresentacao.
- PHP 8.3+
- Slim 4 (
slim/slim,slim/psr7) - Twig (
slim/twig-view,twig/twig) - PHPMailer (
phpmailer/phpmailer) - Apache 2.4 com
mod_rewrite
public/: front controller (index.php),.htaccesse assets.routes/web.php: rotas Slim.src/Controllers/HomeController.php: controller HTTP (PSR-7).src/Core/Env.php: loader simples de.env.views/: templates Twig.storage/: cache e logs de runtime..env.example: modelo de configuracao para novos servidores.
- PHP 8.3 ou superior
- Apache 2.4 com
mod_rewrite - Composer 2
- Permissao de escrita em
storage/
Use .env.example como base para criar o arquivo .env do servidor.
Principais variaveis:
APP_NAMEAPP_MARKAPP_BADGEAPP_PAGE_TITLEAPP_BASEAPP_ENVAPP_PALETTEGITHUB_URLX_URLINSTAGRAM_URLWHATSAPP_URLCONTACT_TOCONTACT_FROMMAIL_DRIVERSMTP_HOSTSMTP_PORTSMTP_USERSMTP_PASSSMTP_ENCRYPTIONSMTP_AUTHSMTP_TIMEOUTRATE_LIMIT_MAX_ATTEMPTSRATE_LIMIT_WINDOW_SECONDS
composer install
cp .env.example .envPara ambiente local, use:
APP_ENV="dev"APP_BASE=""se o projeto abrir na raiz local
Atalho recomendado para dev local sem editar manualmente o .env:
bash scripts/dev-local.shEsse comando aplica APP_BASE vazio e APP_ENV dev apenas durante a sessao local e restaura o .env ao encerrar.
APP_ENV=dev: Twig sem cache,auto_reloadativo e erros detalhados.APP_ENV=production: Twig com cache emstorage/cache/twig,auto_reloaddesativado e middleware de erro em modo restrito.
- Rota:
POST /contato - Controller:
src/Controllers/HomeController.php - Driver suportado:
smtpoumail - Protecoes ativas:
CSRF, honeypot simples e rate limit por IP - Logs:
storage/logs/lead-events.logstorage/logs/contatos-fallback.log
Se MAIL_DRIVER=smtp, configure SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, SMTP_ENCRYPTION, SMTP_AUTH e SMTP_TIMEOUT.
Rate limit padrao:
RATE_LIMIT_MAX_ATTEMPTS=5RATE_LIMIT_WINDOW_SECONDS=600
Este e o fluxo recomendado para o servidor de destino atual, onde o host principal ja existe e o projeto sera publicado em https://srv798468.hstgr.cloud/natalcode/.
git clone https://github.com/luciolemos/natalcode_cloud18344.git /var/www/natalcode
cd /var/www/natalcode
composer install --no-dev --optimize-autoloader
cp .env.example .envPara deploy em subcaminho, use:
APP_ENV="production"APP_BASE="/natalcode"
Preencha tambem:
- identidade visual (
APP_NAME,APP_MARK,APP_BADGE,APP_PAGE_TITLE) - links institucionais
- configuracao de envio de email
Exemplo com Apache rodando como www-data:
sudo chown -R www-data:www-data storage
sudo chmod -R 775 storageNo servidor de destino, adicione ao VirtualHost os aliases abaixo em :80 e :443:
Alias /natalcode/ /var/www/natalcode/public/
Alias /natalcode /var/www/natalcode/public/
<Directory /var/www/natalcode/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>No bloco HTTP (*:80), inclua natalcode no redirect para a barra final:
RewriteCond %{REQUEST_URI} ^/(dashboard|itapiru|mvc|natalcode)$
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI}/ [L,R=301]No bloco HTTPS (*:443), inclua o redirect da URL sem barra:
RewriteRule ^/natalcode$ /natalcode/ [R=301,L]Se o vhost usar segregacao de logs por app, inclua:
SetEnvIf Request_URI "^/natalcode(/|$)" app_natalcode
SetEnvIf Request_URI "^/(?!dashboard(/|$)|itapiru(/|$)|mvc(/|$)|natalcode(/|$)).*" app_root
CustomLog ${APACHE_LOG_DIR}/srv-hstgr-http-natalcode-access.log combined env=app_natalcode
CustomLog ${APACHE_LOG_DIR}/srv-hstgr-https-natalcode-access.log combined env=app_natalcodesudo apache2ctl -t
sudo systemctl reload apache2Em APP_ENV="production", o Twig roda com cache compilado. Após update de código, limpe o cache compilado para evitar HTML antigo.
bash scripts/deploy-post-update.sh --project-root "/var/www/natalcode" --web-user "www-data" --web-group "www-data"Checklist minimo:
https://srv798468.hstgr.cloud/natalcode/abre corretamente- assets carregam sem
404 POST /contatoresponde corretamente- redirects preservam o prefixo
/natalcode storage/cache/twigestorage/logs/recebem escrita
Smoke recomendado no host final:
bash scripts/smoke-contact.sh --url "https://srv798468.hstgr.cloud/natalcode/"Antes de considerar o deploy concluido, valide:
composer testverde no ambiente de build ou homologacaocomposer install --no-dev --optimize-autoloaderexecutado no servidorAPP_ENV="production"eAPP_BASEcoerente com a publicacao- envio real do formulario com recebimento do email
- criacao de entradas em
storage/logs/lead-events.logquando houver submit - ausencia de erro em
storage/logs/contatos-fallback.logapos submit valido - permissoes de escrita em
storage/cache,storage/logsestorage/rate-limit apache2ctl -tsem erro antes do reload
Comandos uteis de verificacao:
composer test
php -r 'require "src/Core/Env.php"; \App\Core\Env::load(".env"); var_export($_ENV["APP_ENV"] ?? null); echo PHP_EOL;'
sudo apache2ctl -t
tail -n 50 storage/logs/lead-events.log
tail -n 50 storage/logs/contatos-fallback.logSe no futuro o projeto for publicado em um host raiz dedicado, entao:
- o codigo pode continuar em
/var/www/natalcode APP_BASE=""- o
DocumentRootdeve apontar para/var/www/natalcode/public
Exemplo:
<VirtualHost *:80>
ServerName exemplo.com
ServerAlias www.exemplo.com
DocumentRoot /var/www/natalcode/public
<Directory /var/www/natalcode/public>
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/natalcode_error.log
CustomLog ${APACHE_LOG_DIR}/natalcode_access.log combined
</VirtualHost>- Em
vhostdedicado:APP_BASE="" - Em subcaminho
/natalcode:APP_BASE="/natalcode"
Se APP_BASE estiver incorreto, podem ocorrer 404 em rotas, redirects ou assets.
Paletas suportadas:
blueredemeraldamberviolet
Resolucao no backend (SSR inicial):
- query string
?palette=<cor> - cookie
palette APP_PALETTE
Resolucao no frontend (apos JS carregar):
- query string
?palette=<cor> localStorage.palette- paleta inicial renderizada pelo backend
Paletas invalidas fazem fallback para blue.
- Acesse sem query string e confirme que a pagina abre na paleta salva anteriormente.
- Clique para trocar entre
blue,redeemeralde valide mudanca imediata sem recarregar. - Recarregue a pagina e confirme persistencia da ultima paleta (sem flicker perceptivel).
- Abra com
?palette=rede confirme prioridade da query string sobre cookie/localStorage. - Abra com
?palette=invalidae confirme fallback parablue. - Confirme que a URL so recebe
?palette=apos clique do usuario (nao automaticamente no primeiro carregamento).
Para validar rapidamente o comportamento de paleta no HTML inicial (sem navegador), execute:
bash scripts/smoke-palette.sh --url "https://srv798468.hstgr.cloud/natalcloud/" --default blueO script cobre:
- query valida
- prioridade query sobre cookie
- prioridade cookie sem query
- query invalida
- fallback default SSR
Para validar o fluxo HTTP basico do formulario de contato (payload invalido com redirect de retorno):
bash scripts/smoke-contact.sh --url "https://srv798468.hstgr.cloud/natalcloud/"O script cobre:
- status HTTP 302 no POST invalido
- redirect para ancora de formulario
- emissao de cookie de sessao
Para validar regressao basica de copy mode SSR e hooks de analytics no JS:
bash scripts/smoke-frontend.sh --url "https://srv798468.hstgr.cloud/natalcloud/"O script cobre:
?copy=growthrefletido no HTML SSR- fallback de copy invalido para
soft - presenca dos hooks
dataLayer,gtag,cta_clickelead_form_submit_attempt
Para validar caminho de sucesso do formulario (exige SMTP funcional/sandbox):
bash scripts/smoke-contact-success.sh --url "http://127.0.0.1:8000/"O script cobre:
- POST valido com status 302
- redirect para
#form-orcamento - flash de sucesso renderizado no HTML
- evento
lead_form_submit_successpresente
Para rodar unitarios + smoke tests em um comando:
bash scripts/run-tests.sh --url "https://srv798468.hstgr.cloud/natalcloud/" --default-palette blueCom teste de sucesso SMTP (quando sandbox estiver disponivel):
bash scripts/run-tests.sh --url "http://127.0.0.1:8000/" --default-palette blue --with-contact-successExecuta validacao de composer, auditoria de dependencias e lint basico:
bash scripts/quality-gate.shExecuta auditoria Lighthouse com thresholds minimos de qualidade:
bash scripts/lighthouse-ci.sh balancedPerfil mais rigoroso (recomendado para staging/release):
bash scripts/lighthouse-ci.sh strictArquivo de configuracao de budget:
.lighthouserc.json.lighthouserc.strict.json
Runner local de um comando (sobe servidor + ajusta ambiente temporario + executa Lighthouse + restaura .env):
bash scripts/lighthouse-local.sh strictExecuta validacao em navegador real (chromium):
bash scripts/smoke-e2e.sh "http://127.0.0.1:8000/"Cobertura atual do E2E:
- troca de paleta com persistencia apos reload
- toggle de copy mode com navegacao growth/soft
Para validar regras centrais de controller (prioridade de paleta e validacao de contato):
php scripts/test-unit.phpCI automatizada:
- workflow em
.github/workflows/ci.yml - sobe SMTP sandbox (Mailpit) local
- executa quality gate (composer validate/audit + lint)
- executa runner unico com unitarios + smoke tests (paleta, contato, frontend e contato com sucesso)
- aplica budget Lighthouse
perfil usado no CI:
strict - roda smoke E2E em navegador real (Playwright)
- Publique apenas o diretorio
public/no Apache - Nao versione o arquivo
.env - Use
APP_ENV="production"em servidor publico - Restrinja escrita apenas a
storage/ - Configure SMTP com credenciais do servidor de destino
- Revise o rate limit do formulario conforme o perfil de trafego do site
- Prefira HTTPS no host final
- Rode
apache2ctl -tantes de qualquer reload
Comandos uteis:
composer install --no-dev --optimize-autoloader
composer test
bash scripts/deploy-post-update.sh --project-root "/var/www/natalcode" --web-user "www-data" --web-group "www-data"
sudo apache2ctl -t
sudo systemctl reload apache2- Guia operacional de centralizacao:
docs/centralizacao.md - Exemplo de vhost compartilhado:
docs/apache-vhost-srv798468-natalcode.conf - Exemplo de
.envpara subcaminho:docs/.env.natalcode.example - Script de paleta em lote:
scripts/set-palettes.sh - Conversao de imagens para WebP:
scripts/convert-webp.php