Desafio PHP
Sistema de templates com caminhos seguros
Enunciado
Crie uma função renderizar($template, $dados) que inclui um arquivo de template da pasta templates/ usando __DIR__ para montar o caminho. A função deve usar include para que, se o template não existir, exiba uma mensagem de erro amigável e continue. Os dados devem ser extraídos para variáveis locais antes da inclusão. Crie dois templates: home.php que exibe "Bem-vindo, $nome!" e sobre.php que exibe "Sobre nós". No script principal, chame renderizar('home', ['nome' => 'Carlos']) e renderizar('sobre', []). Depois, tente renderizar um template inexistente e mostre a mensagem de erro. O script deve continuar após o erro.
Requisitos
- A função
renderizardeve usarincludecom caminho baseado em__DIR__. - Os dados devem ser extraídos com
extract()antes do include. - Deve tratar template inexistente exibindo
Template não encontrado: <nome>e continuar. - A saída deve conter as três linhas:
Bem-vindo, Carlos!,Sobre nóseTemplate não encontrado: contato.
Código inicial
<?php
// funcoes.php
function renderizar($template, $dados) {
// Monte o caminho usando __DIR__ . '/templates/' . $template . '.php'
// Verifique se o arquivo existe; se não, exiba mensagem e retorne
// Extraia os dados para variáveis
// Inclua o template
}
?>
<?php
// home.php (dentro de templates/)
// Exiba "Bem-vindo, $nome!"
?>
<?php
// sobre.php (dentro de templates/)
// Exiba "Sobre nós"
?>
<?php
// index.php
require __DIR__ . '/funcoes.php';
renderizar('home', ['nome' => 'Carlos']);
renderizar('sobre', []);
renderizar('contato', []);
?>
Saída esperada
Bem-vindo, Carlos!
Sobre nós
Template não encontrado: contato
Ver dica
Use file_exists() para verificar o arquivo antes de incluir. extract() cria variáveis a partir das chaves do array.
Mostrar solução
<?php
// funcoes.php
function renderizar($template, $dados) {
// Monta o caminho absoluto para o template
$caminho = __DIR__ . '/templates/' . $template . '.php';
// Verifica se o arquivo existe
if (!file_exists($caminho)) {
echo "Template não encontrado: $template\n";
return;
}
// Extrai os dados para variáveis locais
extract($dados);
// Inclui o template (include permite continuar se algo falhar)
include $caminho;
}
?>
<?php
// templates/home.php
echo "Bem-vindo, $nome!\n";
?>
<?php
// templates/sobre.php
echo "Sobre nós\n";
?>
<?php
// index.php
require __DIR__ . '/funcoes.php';
renderizar('home', ['nome' => 'Carlos']);
renderizar('sobre', []);
renderizar('contato', []);
?>
Passo a passo
- A função
renderizarrecebe o nome do template (sem extensão) e um array de dados. - Monta o caminho completo usando
__DIR__ . '/templates/' . $template . '.php', garantindo que o caminho seja absoluto e independente do diretório atual. - Usa
file_exists()para verificar se o arquivo existe. Se não, exibe a mensagemTemplate não encontrado: <nome>e retorna, evitando erro fatal. - Se existir, usa
extract($dados)para transformar as chaves do array em variáveis locais (ex.:$nome). - Inclui o template com
include. Como éinclude, se algo der errado dentro do template, o script continua (embora neste caso não haja erro). - No
index.php, incluifuncoes.phpcomrequiree chamarenderizartrês vezes.
Por que funciona
O uso de __DIR__ garante que o caminho para a pasta templates seja sempre correto, independentemente de onde o script for executado. A verificação com file_exists evita que um template inexistente cause um aviso do include. O extract permite que o template acesse os dados como variáveis simples, mantendo o código limpo. O include é adequado porque um template ausente não deve interromper todo o sistema; apenas exibimos uma mensagem amigável.
Erros comuns
- Não usar
__DIR__e montar o caminho com'templates/' . $template . '.php': se o script for chamado de outro diretório, o arquivo não será encontrado. - Usar
requireem vez deincludedentro da função: se o template não existir, o script seria interrompido, impedindo a mensagem amigável. - Esquecer de verificar
file_existsantes doinclude: o PHP emitiria um aviso (Warning) e continuaria, mas a saída ficaria poluída. - Não extrair os dados: o template não teria acesso às variáveis, causando erros de variável indefinida.
Outra forma de resolver
Usar require_once para incluir os templates, mas isso não é necessário aqui, pois cada template é incluído uma vez. Também poderia usar um autoloader ou funções de template mais robustas, mas para este exemplo, a abordagem com include e __DIR__ é suficiente.
Saída esperada
Bem-vindo, Carlos!
Sobre nós
Template não encontrado: contato