Capítulo 4
Projeto final publicação e HTML reutilizável com PHP
16 min de leitura 2.849 palavras 6 gravuras
Planejamento integração validação hospedagem e manutenção
Reúna o que foi aprendido em um site completo publique com segurança e use PHP para compartilhar cabeçalho navegação e rodapé entre páginas.
Como usar este capítulo
A último capítulo transforma exercícios separados em um projeto coerente. Primeiro você planeja conteúdo e arquivos. Depois monta a versão estática, testa, publica e registra uma rotina de manutenção. A parte final apresenta PHP como etapa opcional para remover repetição entre páginas.
Há um projeto funcional na pasta projeto-exemplo. Abra os arquivos, compare com os trechos do capítulo e altere o conteúdo. Não publique os exemplos sem revisão; eles incluem textos fictícios e endereços de demonstração.
Objetivos de aprendizagem
- Planejar um site pequeno antes de escrever código.
- Montar páginas coerentes com HTML semântico e CSS responsivo.
- Verificar conteúdo links acessibilidade desempenho e segurança básica.
- Publicar um site estático e diagnosticar diferenças do ambiente final.
- Distinguir site estático de site processado no servidor.
- Executar PHP apenas no computador local durante o desenvolvimento.
- Reutilizar fragmentos com
includee caminhos baseados em__DIR__. - Marcar a página atual na navegação sem duplicar o menu.
- Manter e atualizar o projeto depois da primeira publicação.
Sumário
**1. **Planejamento do projeto
**2. **Arquitetura de conteúdo
**3. **Montagem da versão estática
**4. **Revisão técnica
**5. **Publicação
**6. **Rotina de atualização
**7. **Sites estáticos e dinâmicos
**8. **Primeiro código PHP
**9. **Fragmentos reutilizáveis
**10. **Conversão das páginas
**11. **Navegação dinâmica
**12. **Segurança básica em PHP
**13. **Avaliação final
**14. **Continuidade dos estudos
Unidade 1 Planejamento do projeto
Um site pequeno também se beneficia de planejamento. Antes de abrir o editor, responda:
- Quem deve usar o site?
- O que essa pessoa precisa encontrar?
- Quais páginas resolvem essa necessidade?
- Qual conteúdo já existe e qual ainda precisa ser escrito?
- Que imagens podem ser publicadas legalmente?
- Como o site será atualizado? O projeto de demonstração chama-se Caderno de Trilhas. Seu objetivo é reunir artigos curtos, uma apresentação, um currículo de exemplo, uma página de contato e uma área leve com conteúdo expansível.
Escopo
Critério de conclusão
O projeto estará pronto quando uma pessoa puder abrir a página inicial, entender o assunto, navegar por teclado, ler em tela estreita e chegar a todas as páginas sem erro. A aparência deve apoiar esse percurso, não competir com ele.
Unidade 2 Arquitetura de conteúdo
Mapa do site
PLAINTEXT
Início
├── Blog
│ ├── Primeira caminhada
│ └── Organizando as notas
├── Sobre
├── Currículo
├── Contato
└── Divertido
Um mapa raso é simples de navegar e de manter. Se uma página exige muitos cliques, verifique se ela pertence a uma seção principal.
Estrutura de arquivos
PLAINTEXT
caderno-trilhas/
├── index.html
├── sobre.html
├── curriculo.html
├── contato.html
├── divertido.html
├── blog/
│ ├── index.html
│ ├── primeira-caminhada.html
│ └── organizando-as-notas.html
├── css/
│ └── styles.css
├── imagens/
└── midia/
Mantenha nomes de arquivos relacionados aos títulos, mas estáveis. Trocar sobre.html depois da publicação quebra favoritos e links externos. Se a mudança for inevitável, configure um redirecionamento na hospedagem.
Modelo de página
Todas as páginas estáticas podem partir do mesmo esqueleto.
HTML
<!doctype html>
<html lang="pt-BR">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Descrição curta e específica da página.">
<title>Título da página | Caderno de Trilhas</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<a class="pular" href="#conteudo">Pular para o conteúdo</a>
<header>
<nav aria-label="Navegação principal">
...
</nav>
</header>
<main id="conteudo">
...
</main>
<footer>
<p>Conteúdo de demonstração.</p>
</footer>
</body>
</html>
meta name="description" resume a página para mecanismos de busca e compartilhamentos. Escreva uma descrição específica; não repita o mesmo texto em todas as páginas.
Unidade 3 Montagem da versão estática
Página inicial
HTML
<main id="conteudo">
<section class="apresentacao">
<p class="rotulo">Caderno de estudo</p>
<h1>Caderno de Trilhas</h1>
<p>Notas, roteiros e aprendizados reunidos em um site responsivo.</p>
<p><a class="botao" href="blog/index.html">Explorar os artigos</a></p>
</section>
<section aria-labelledby="recentes">
<h2 id="recentes">Artigos recentes</h2>
<div class="grade-artigos">
<article class="cartao">
<h3><a href="blog/primeira-caminhada.html">Primeira caminhada</a></h3>
<p>Um roteiro curto para testar o projeto e o equipamento.</p>
</article>
<article class="cartao">
<h3><a href="blog/organizando-as-notas.html">Organizando as notas</a></h3>
<p>Como separar registros de percurso e listas práticas.</p>
</article>
</div>
</section>
</main>

Versão em tela estreita

Menu completo
HTML
<nav aria-label="Navegação principal">
<a href="index.html" aria-current="page">Início</a>
<a href="blog/index.html">Blog</a>
<a href="sobre.html">Sobre</a>
<a href="curriculo.html">Currículo</a>
<a href="contato.html">Contato</a>
<a href="divertido.html">Divertido</a>
</nav>
Nas páginas dentro de blog, os destinos da raiz começam com ../.
HTML
<nav aria-label="Navegação principal">
<a href="../index.html">Início</a>
<a href="index.html" aria-current="page">Blog</a>
<a href="../sobre.html">Sobre</a>
<a href="../curriculo.html">Currículo</a>
<a href="../contato.html">Contato</a>
<a href="../divertido.html">Divertido</a>
</nav>
Títulos de página
Cada arquivo deve ter um <title> único e um <h1> que identifique o conteúdo. Eles podem ser parecidos, mas têm funções diferentes: <title> aparece na aba e em resultados; <h1> aparece no documento.
Formulário de demonstração
O arquivo de exemplo usa um formulário sem destino real. Para um site publicado, conecte-o a um serviço ou código de servidor que você administra. Leia a política de privacidade e colete apenas o necessário.
HTML
<form action="" method="post">
<label for="nome">Nome</label>
<input id="nome" name="nome" autocomplete="name" required>
<label for="email">E-mail</label>
<input id="email" name="email" type="email" autocomplete="email" required>
<label for="mensagem">Mensagem</label>
<textarea id="mensagem" name="mensagem" rows="6" maxlength="1000" required></textarea>
<button type="submit">Enviar mensagem</button>
</form>
**ATENÇÃO: **Um formulário com action="" não envia a mensagem para um sistema útil. Ele existe para estudar HTML e validação. Não anuncie um canal de contato até configurar processamento e testar o recebimento.
Unidade 4 Revisão técnica
Revisão não é uma leitura rápida da página inicial. Faça um percurso que cubra conteúdo, código, telas e condições de erro.
Conteúdo
- Cada página explica seu assunto logo no início.
- Títulos seguem ordem lógica.
- Links descrevem o destino.
- Datas, endereços e nomes foram conferidos.
- Textos fictícios estão identificados ou foram substituídos.
- Imagens têm autorização de uso e texto alternativo adequado.
HTML
- Há doctype idioma codificação viewport título e descrição.
- Existe um único
<main>visível. idnão se repete.- O menu marca apenas a página atual.
- Tabelas possuem legenda e cabeçalhos.
- Formulários possuem labels ligados aos controles.
- O validador não mostra erros estruturais.
CSS
- O site funciona a 320 768 e 1280 pixels.
- Não há rolagem horizontal inesperada.
- Foco de teclado está visível.
- Contraste foi verificado nos temas claro e escuro.
- Zoom de 200 por cento não sobrepõe conteúdo.
- Impressão do currículo não corta informação.
Arquivos e rede
- A aba Rede não mostra
404. - Imagens possuem dimensões e tamanho de arquivo razoável.
- Nenhum arquivo privado está dentro da pasta publicada.
- Bibliotecas externas têm origem conhecida e versão registrada.
- Console não apresenta erro relacionado ao projeto.
Privacidade e segurança
- Não há senha token chave de API ou credencial no HTML CSS JavaScript comentários ou histórico público.
- Formulários coletam apenas o necessário.
- Links externos que abrem nova aba usam
rel="noopener". - Iframes usam fontes confiáveis e permissões limitadas.
- O servidor local escuta em
127.0.0.1.

Unidade 5 Publicação
Hospedagem estática
Uma hospedagem estática entrega HTML CSS imagens e JavaScript como arquivos. Ela é suficiente para a versão principal do projeto. Neocities oferece gerenciamento pelo navegador. GitHub Pages publica conteúdo de um repositório. Outros provedores trabalham com envio manual ou integração com Git.
Escolha conforme sua experiência e requisitos. Confira limite de espaço, domínio personalizado, política de uso, coleta de dados e processo de remoção. Recursos e preços podem mudar.
Envio manual
**1. **Faça uma cópia local da versão pronta.
**2. **Envie os arquivos preservando a estrutura de pastas.
**3. **Abra a página inicial no endereço público.
**4. **Percorra o menu inteiro.
**5. **Abra ferramentas do navegador e procure 404.
**6. **Teste em janela estreita e em outro dispositivo.
Publicação a partir de repositório
Em um serviço integrado ao Git, cada alteração confirmada pode iniciar uma publicação. Isso oferece histórico e reversão, mas exige compreender repositório, commit e branch. Não guarde credenciais no repositório.
Domínio e HTTPS
Use HTTPS no site público. A hospedagem normalmente fornece um endereço inicial e um certificado. Domínio personalizado exige configurar DNS; siga a documentação do provedor e espere o tempo de propagação. Não desative validação de certificado para contornar erros.
Erros frequentes
Unidade 6 Rotina de atualização
Publicar uma vez não encerra o trabalho. Defina um processo curto e repetível.
**1. **Edite no computador.
**2. **Inicie o servidor local.
**3. **Teste as páginas alteradas e seus links de entrada.
**4. **Valide o HTML.
**5. **Crie uma cópia ou commit.
**6. **Publique.
**7. **Confira o endereço final.
Evitar versões confusas
Não mantenha arquivos como index-novo.html, index-final.html e index-final-agora-vai.html na pasta publicada. Use controle de versão ou uma pasta de backup fora da raiz do site.
Links permanentes
Depois que uma página recebe visitas, seu endereço passa a ser uma referência. Evite renomear arquivos e pastas. Se precisar reorganizar, use redirecionamentos oferecidos pela hospedagem.
Registro de mudanças
Um arquivo CHANGELOG.md simples pode anotar data e resumo das mudanças. Ele não precisa ser publicado. Em um repositório Git, mensagens de commit já cumprem parte dessa função.
Unidade 7 Sites estáticos e dinâmicos
Em um site estático, o servidor entrega o arquivo que já existe. Em um site dinâmico, um programa roda no servidor e gera a resposta. O navegador recebe HTML nos dois casos.

PHP é uma linguagem de programação executada no servidor. Ela pode montar páginas, acessar banco de dados e tratar formulários. Neste capítulo, o uso é restrito a duas tarefas: mostrar um valor dinâmico e reutilizar fragmentos.
Quando continuar com HTML estático
Use HTML puro quando o site tem poucas páginas e muda pouco. É simples de hospedar, rápido e tem superfície de ataque pequena.
Quando considerar processamento no servidor
Considere PHP quando há muitas páginas compartilhando elementos, dados vindos de formulário, conteúdo gerado a partir de banco ou regras que precisam rodar antes da resposta. Isso exige hospedagem compatível, atualizações de segurança e cuidado com entrada de dados.
Unidade 8 Primeiro código PHP
Crie uma cópia do projeto antes da conversão. Renomeie index.html para index.php. Um arquivo PHP pode conter HTML comum.
Para testar, instale uma versão suportada do PHP e execute na raiz do projeto:
POWERSHELL
php -S 127.0.0.1:8000 -t .
Abra http://localhost:8000/. O código PHP não funciona ao abrir o arquivo com dois cliques.
Bloco PHP
PHP
<?php
$ano = date('Y');
?>
<footer>
<p>Conteúdo atualizado em <?= $ano ?>.</p>
</footer>
<?php abre o código. ?> fecha. A sintaxe <?= ... ?> imprime uma expressão. date('Y') devolve o ano conforme a configuração do servidor.
O navegador não deve receber o código PHP. Abra o código-fonte da página no navegador e confirme que aparece apenas o resultado em HTML.
**ATENÇÃO: **Se o navegador exibir <?php ... ?>, o arquivo não foi processado por PHP. Pare e corrija o servidor. Publicar código-fonte pode revelar lógica ou credenciais que nunca deveriam estar no arquivo.
Unidade 9 Fragmentos reutilizáveis
Crie uma pasta includes e três arquivos.
PLAINTEXT
includes/
├── cabecalho.php
├── navegacao.php
└── rodape.php

Cabeçalho
PHP
<!-- includes/cabecalho.php -->
<header>
<p class="marca"><a href="/">Caderno de Trilhas</a></p>
<?php require __DIR__ . '/navegacao.php'; ?>
</header>
Navegação
HTML
<!-- includes/navegacao.php -->
<nav aria-label="Navegação principal">
<a href="/">Início</a>
<a href="/blog/">Blog</a>
<a href="/sobre.php">Sobre</a>
<a href="/curriculo.php">Currículo</a>
<a href="/contato.php">Contato</a>
<a href="/divertido.php">Divertido</a>
</nav>
Rodapé
PHP
<!-- includes/rodape.php -->
<footer>
<p>Conteúdo atualizado em <?= date('Y') ?>.</p>
</footer>
Include e require
include emite um aviso quando o arquivo não é encontrado e tenta continuar. require interrompe a execução. Para cabeçalho e navegação essenciais, require costuma ser mais adequado.
__DIR__ contém a pasta do arquivo em execução. Usá-lo torna o caminho do fragmento previsível, sem depender do diretório atual do processo.
PHP
<?php require __DIR__ . '/includes/cabecalho.php'; ?>
Em um arquivo dentro de blog, suba um nível no caminho de arquivos do servidor.
PHP
<?php require __DIR__ . '/../includes/cabecalho.php'; ?>
Observe a diferença: o caminho de require localiza um arquivo no servidor; o href do link localiza uma página para o navegador.
Unidade 10 Conversão das páginas
Converta um arquivo por vez.
**1. **Renomeie .html para .php.
**2. **Troque cabeçalho repetido por require.
**3. **Troque rodapé repetido por require.
**4. **Atualize os links internos para os novos nomes.
**5. **Abra a página pelo servidor local.
**6. **Veja o código-fonte gerado e valide o HTML.
Página da raiz
PHP
<!doctype html>
<html lang="pt-BR">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Sobre o projeto | Caderno de Trilhas</title>
<link rel="stylesheet" href="/css/styles.css">
</head>
<body>
<a class="pular" href="#conteudo">Pular para o conteúdo</a>
<?php require __DIR__ . '/includes/cabecalho.php'; ?>
<main id="conteudo">
<h1>Sobre o projeto</h1>
<p>Conteúdo da página.</p>
</main>
<?php require __DIR__ . '/includes/rodape.php'; ?>
</body>
</html>
Página do blog
PHP
<?php require __DIR__ . '/../includes/cabecalho.php'; ?>
O caminho de CSS pode começar em / quando o servidor atende o projeto como raiz. Se a hospedagem colocar o site em uma subpasta, defina uma URL base de configuração ou use caminhos relativos.
Atualizar links
Procure por .html em toda a pasta. Alguns links podem apontar para páginas renomeadas. Recursos como imagens e CSS não mudam de extensão.
Unidade 11 Navegação dinâmica
O menu compartilhado perdeu a indicação da página atual. Uma função pode comparar o endereço pedido com o destino de cada item.
Função segura para o exemplo
Crie includes/funcoes.php.
PHP
<?php
declare(strict_types=1);
function aria_atual(string $destino): string
{
$caminho = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?: '/';
if ($caminho === $destino) {
return 'page';
}
if ($destino !== '/' && str_starts_with($caminho, rtrim($destino, '/') . '/')) {
return 'true';
}
return '';
}
O primeiro teste devolve page quando o destino é exatamente a página atual. O segundo devolve true quando a pessoa está numa subpágina daquela seção. A página inicial recebe tratamento separado para não combinar com todos os caminhos.
Usar a função
PHP
<?php require_once __DIR__ . '/funcoes.php'; ?>
<nav aria-label="Navegação principal">
<a href="/" <?= aria_atual('/') ? 'aria-current="' . aria_atual('/') . '"' : '' ?>>
Início
</a>
<a href="/blog/" <?= aria_atual('/blog') ? 'aria-current="' . aria_atual('/blog') . '"' : '' ?>>
Blog
</a>
<a href="/sobre.php" <?= aria_atual('/sobre.php') ? 'aria-current="' . aria_atual('/sobre.php') . '"' : '' ?>>
Sobre
</a>
</nav>
Esse código repete a chamada da função. Podemos deixá-lo mais legível com uma função que monte apenas o atributo.
PHP
<?php
function atributo_aria_atual(string $destino): string
{
$valor = aria_atual($destino);
if ($valor === '') {
return '';
}
return 'aria-current="' . $valor . '"';
}
PHP
<nav aria-label="Navegação principal">
<a href="/" <?= atributo_aria_atual('/') ?>>Início</a>
<a href="/blog/" <?= atributo_aria_atual('/blog') ?>>Blog</a>
<a href="/sobre.php" <?= atributo_aria_atual('/sobre.php') ?>>Sobre</a>
</nav>

Testar a função
Abra:
/e confirme Início comaria-current="page"./sobre.phpe confirme Sobre comaria-current="page"./blog/e confirme Blog comaria-current="page"./blog/primeira-caminhada.phpe confirme Blog comaria-current="true". Inspecione o HTML gerado. Links não ativos não devem receber atributo vazio.
Unidade 12 Segurança básica em PHP
O exemplo de includes não recebe dados de pessoas, mas qualquer expansão do projeto precisa seguir regras básicas.
Não exponha o servidor de desenvolvimento
Use 127.0.0.1. O servidor embutido do PHP não foi projetado para rede pública. Uma hospedagem de produção precisa de servidor configurado, atualizações, HTTPS, logs e política de backup.
Saída de texto
Quando um valor vem de formulário, URL ou banco de dados, escape-o antes de inserir em HTML.
PHP
<?php
$nome = $_POST['nome'] ?? '';
$nome_seguro = htmlspecialchars($nome, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
?>
<p>Olá, <?= $nome_seguro ?>.</p>
htmlspecialchars impede que sinais de HTML presentes no texto sejam interpretados como marcação. Isso não resolve todos os riscos, mas é obrigatório ao inserir texto não confiável em HTML.
Validação
Valide no servidor mesmo que o formulário use required e type="email".
PHP
<?php
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if ($email === false || $email === null) {
http_response_code(422);
exit('Endereço de e-mail inválido.');
}
Mensagens públicas não devem revelar caminhos internos, consultas ou rastros de exceção. Registre detalhes em local protegido e mostre uma orientação curta para a pessoa.
Arquivos de configuração
Não escreva senhas no repositório ou na pasta pública. Use variáveis de ambiente ou mecanismo seguro oferecido pela hospedagem. Se uma credencial foi publicada, removê-la do arquivo atual não basta: revogue e substitua a credencial.
Includes
Não monte o caminho de include diretamente com um valor recebido pela URL. Isso pode permitir leitura ou execução de arquivos indevidos.
PHP
// Não faça isto
include $_GET['pagina'];
Use uma lista explícita de destinos válidos quando precisar selecionar um arquivo.
PHP
<?php
$paginas = [
'inicio' => __DIR__ . '/paginas/inicio.php',
'sobre' => __DIR__ . '/paginas/sobre.php',
];
$chave = $_GET['pagina'] ?? 'inicio';
$arquivo = $paginas[$chave] ?? $paginas['inicio'];
require $arquivo;
Unidade 13 Avaliação final
Entrega prática
Entregue um site com no mínimo seis páginas ou rotas:
- Início.
- Blog.
- Um artigo.
- Sobre.
- Currículo ou portfólio.
- Contato ou página de recursos.
O site deve conter texto estruturado, lista, figura, tabela,
<details>, formulário, navegação e folha CSS própria. A versão PHP é opcional; se escolhida, cabeçalho, menu e rodapé devem vir de includes.
Rubrica
Teste final
**1. **Inicie o site localmente.
**2. **Comece em uma janela anônima ou perfil limpo.
**3. **Percorra o menu com mouse e teclado.
**4. **Abra todos os links internos.
**5. **Envie o formulário apenas se houver destino de teste.
**6. **Altere largura e zoom.
**7. **Verifique temas claro e escuro.
**8. **Valide ao menos a página inicial um artigo e o formulário.
**9. **Confira Rede e Console.
**10. **Publique e repita os testes no endereço final.
Questões de revisão
**1. **Por que um site deve ser testado depois da publicação?
**2. **Qual é a diferença entre caminho de require e href?
**3. **Quando require é preferível a include?
**4. **Para que serve __DIR__?
**5. **Por que o navegador não deve receber o código PHP?
**6. **O que muda entre aria-current="page" e aria-current="true" no menu do exemplo?
**7. **Por que htmlspecialchars é necessário?
**8. **Por que o servidor embutido do PHP não deve ficar público?
**9. **O que fazer se uma credencial entrou em um repositório público?
Respostas comentadas
**1. **Servidor caminhos cache certificados e arquivos enviados podem se comportar de modo diferente do ambiente local.
**2. **require localiza um arquivo no sistema do servidor; href cria um endereço que o navegador visitará.
**3. **Quando o fragmento é essencial e a página não deve continuar sem ele.
**4. **Ele fornece a pasta do arquivo atual e estabiliza caminhos de inclusão.
**5. **PHP contém lógica de servidor e pode conter detalhes que não pertencem à resposta. O servidor deve executar o código e enviar HTML.
**6. **page indica correspondência exata; true indica que o item representa uma seção ancestral da página aberta.
**7. **Para que texto não confiável não seja interpretado como HTML ao ser exibido.
**8. **Ele foi criado para desenvolvimento controlado e não oferece a preparação de um servidor de produção.
**9. **Revogar e substituir a credencial, limpar o uso indevido e revisar o histórico e os acessos; apenas apagar a linha atual não neutraliza o segredo.
Unidade 14 Continuidade dos estudos
Você já possui base suficiente para aprender por documentação e construir projetos próprios. Escolha o próximo assunto a partir de uma necessidade concreta.
JavaScript
Estude variáveis, funções, eventos e manipulação do DOM quando precisar de comportamento no navegador. Preserve a funcionalidade básica sem JavaScript quando isso for possível.
Controle de versão
Git registra mudanças e facilita voltar a uma versão conhecida. Comece com repositório local, commits pequenos e mensagens que expliquem a alteração.
Hospedagem e domínio
Aprenda DNS, HTTPS, cabeçalhos HTTP, cache e redirecionamentos. Ao sair de hospedagem gerenciada, inclua atualizações e backups no plano.
Backend e banco de dados
Depois de PHP básico, estude requisições, sessões, autenticação, consultas parametrizadas, migrações e proteção contra ataques comuns. Não construa autenticação real copiando um exemplo curto.
Acessibilidade
Teste com teclado, zoom e ao menos um leitor de tela. Conheça WCAG e use auditorias automáticas como apoio, não como prova completa.
Projeto próprio
Um pequeno site mantido por meses ensina mais sobre URLs, conteúdo e compatibilidade que uma sequência de exercícios descartáveis. Publique algo que você possa revisar, corrigir e ampliar.