Introdução
Antes de escrever qualquer programa, você precisa de um lugar onde o PHP possa rodar. Esse lugar é o seu ambiente de desenvolvimento — a combinação de ferramentas instaladas na sua máquina que permite escrever, executar e depurar código PHP. Configurar esse ambiente corretamente desde o início poupa horas de frustração no futuro.
Neste artigo vamos instalar o PHP, conhecer o servidor embutido, escolher um editor de código, entender a estrutura básica de um arquivo PHP e rodar nosso primeiro programa de verdade.
Instalando o PHP
A instalação varia conforme o sistema operacional. Em todos os casos, o objetivo é ter o comando php disponível no terminal.
Linux (Ubuntu/Debian):
sudo apt update
sudo apt install php php-cli php-mbstring php-xml php-curl
macOS (com Homebrew):
brew install php
Se você não tem o Homebrew instalado, acesse https://brew.sh e siga as instruções — é o gerenciador de pacotes padrão para macOS.
Windows:
A forma mais direta é instalar o XAMPP, disponível em https://www.apachefriends.org. Ele inclui PHP, Apache e MySQL em um único instalador com interface gráfica. Após a instalação, adicione o caminho do PHP ao PATH do sistema para usar o comando php no terminal.
Alternativamente, baixe o PHP diretamente em https://windows.php.net/download e siga as instruções de configuração manual do PATH.
Após qualquer instalação, abra o terminal e confirme:
php --version
A saída deve mostrar algo como PHP 8.4.3 (cli) — o número exato varia conforme a instalação. Se apareceu, está funcionando. Vale conferir a versão: a partir de setembro de 2026, só os ramos 8.2 e 8.3 (apenas segurança) e 8.4 e 8.5 (suporte ativo) ainda recebem correção — instalação mais antiga que isso não deve ir para um servidor.
O servidor embutido do PHP
Para desenvolvimento local, o PHP possui um servidor web embutido que elimina a necessidade de instalar Apache ou Nginx. Você aponta para uma pasta e ele serve os arquivos PHP diretamente:
# Navegue até a pasta do projeto
cd meu-projeto
# Inicie o servidor na porta 8000
php -S localhost:8000
Abra o navegador em http://localhost:8000. O PHP servirá os arquivos da pasta atual. Para encerrar, pressione Ctrl + C no terminal.
Você também pode especificar um arquivo de entrada específico, útil quando há um ponto de entrada único:
# Usar index.php como ponto de entrada para todas as requisições
php -S localhost:8000 index.php
Esse servidor é suficiente para os Módulos 1 a 5 desta série. Nos módulos avançados, usaremos Docker para ambientes mais próximos da produção real.
Escolhendo o editor de código
Você pode escrever PHP em qualquer editor de texto, mas ferramentas certas aumentam a produtividade de forma significativa.
VS Code é a escolha mais popular e a recomendada para esta série. Gratuito, extensível e com excelente suporte a PHP. Baixe em https://code.visualstudio.com e instale as extensões:
- PHP Intelephense — autocomplete inteligente, navegação de código, detecção de erros em tempo real
- PHP Debug — integração com Xdebug para depuração com breakpoints
- PHP CS Fixer — formata o código automaticamente seguindo os padrões PSR
PhpStorm é o IDE profissional mais completo para PHP, desenvolvido pela JetBrains. Disponível em https://www.jetbrains.com/phpstorm. É pago, com período de avaliação de 30 dias. Oferece recursos avançados que fazem diferença em projetos grandes. Vale considerar quando você estiver no Módulo 7 em diante.
Para esta série, VS Code com Intelephense atende muito bem.
Estrutura de um arquivo PHP
Um arquivo PHP tem extensão .php. Dentro dele, você pode escrever HTML puro, PHP puro, ou misturar os dois. O código PHP sempre fica dentro das tags de abertura e fechamento:
<?php
// Código PHP aqui
?>
Quando o arquivo contém apenas PHP — sem HTML —, a boa prática é omitir a tag de fechamento ?>. Isso evita que espaços em branco acidentais sejam enviados ao navegador antes dos headers HTTP, o que causa erros em redirecionamentos e cookies.
<?php
// Arquivo puramente PHP: sem tag de fechamento no final
// Isso é um padrão da comunidade — siga sempre
echo "Olá, mundo!";
Seu primeiro programa
Crie uma pasta chamada php-curso e dentro dela um arquivo index.php com o seguinte conteúdo:
<?php
// echo envia texto para a saída — navegador ou terminal
echo "Olá, Mundo!\n";
// Expressões matemáticas são avaliadas antes de serem exibidas
echo 2 + 2;
echo "\n";
// date() é uma função nativa que formata a data atual
// "d/m/Y" = dia/mês/ano com quatro dígitos
echo "Hoje é: " . date("d/m/Y");
echo "\n";
// phpinfo() exibe informações completas sobre a instalação do PHP
// Extremamente útil para diagnóstico — mas nunca deixe em produção
// phpinfo();
No terminal, dentro da pasta php-curso, rode:
php index.php
Saída esperada:
Olá, Mundo!
4
Hoje é: 05/03/2026
Você pode também iniciar o servidor embutido e acessar pelo navegador — o resultado será o mesmo conteúdo, mas sem quebras de linha visíveis, pois o navegador interpreta HTML, e \n não é uma quebra de linha em HTML (para isso seria necessário <br>).
Misturando PHP com HTML
Quando rodando no servidor web, o PHP gera HTML. Essa é a forma mais comum de usar PHP em projetos web tradicionais:
<?php
// Definimos as variáveis no início do arquivo — antes de qualquer HTML
$nome = "Ricardo";
$data = date("d/m/Y");
$hora = date("H:i");
?>
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>Meu primeiro PHP</title>
</head>
<body>
<h1>Bem-vindo, <?= $nome ?>!</h1>
<!--
<?= $variavel ?> é um atalho para <?php echo $variavel; ?>
Use-o em templates HTML para manter o código mais limpo
-->
<p>Hoje é <?= $data ?>, são <?= $hora ?>.</p>
</body>
</html>
O <?= é chamado de short echo tag. É um atalho para <?php echo. Use-o em arquivos de template onde PHP e HTML se misturam com frequência — o código fica mais limpo e legível.
Depurando com var_dump e print_r
Dois dos comandos mais úteis para inspecionar valores durante o desenvolvimento:
<?php
$nome = "Ana";
$idade = 28;
$ativo = true;
$notas = [9.5, 8.0, 7.5];
// echo exibe o valor como string — simples, mas sem informação de tipo
echo $nome;
echo "\n";
// var_dump exibe o tipo e o valor — essencial para depuração
// Mostra: string(3) "Ana"
var_dump($nome);
// var_dump em booleano mostra true ou false com o tipo
// Mostra: bool(true)
var_dump($ativo);
// var_dump em array mostra toda a estrutura com tipos
var_dump($notas);
// print_r exibe arrays e objetos de forma mais legível para humanos
// Menos verboso que var_dump — bom para estruturas complexas
print_r($notas);
Saída de var_dump($notas):
array(3) {
[0] => float(9.5)
[1] => float(8)
[2] => float(7.5)
}
Saída de print_r($notas):
Array
(
[0] => 9.5
[1] => 8
[2] => 7.5
)
Use var_dump quando precisar saber o tipo exato. Use print_r quando só precisar ver a estrutura dos dados.
Boas práticas desde o início
Alguns hábitos que farão diferença ao longo de toda a sua carreira:
Use UTF-8 sempre. Declare charset=UTF-8 em seus HTMLs e salve seus arquivos em UTF-8 no editor. Isso evita problemas com acentuação que são frustrantes de diagnosticar.
Omita a tag de fechamento ?> em arquivos puramente PHP. É um padrão do PSR-12, o guia de estilo oficial da comunidade PHP.
Use 4 espaços por nível de indentação. Também é definido pelo PSR-12. Configure seu editor para inserir espaços automaticamente ao pressionar Tab.
Nomeie variáveis com clareza. $nomeDoUsuario é infinitamente melhor que $n. Código é lido muito mais do que escrito — clareza é respeito pelo seu eu futuro, e por quem trabalhar com você.
Um arquivo, uma responsabilidade. Desde cedo, evite arquivos PHP gigantes que fazem tudo ao mesmo tempo. Separar responsabilidades é o fundamento de todo bom design de software.
Um ambiente bem montado não se percebe: ele some, e sobra o trabalho. O que você instalou aqui — interpretador na linha de comando, servidor embutido, editor com análise em tempo real — é suficiente para todo o começo da série, e nada disso precisa ser trocado quando o projeto crescer; o que muda é o que se acrescenta em volta. Guarde o hábito de conferir php --version e php -m antes de culpar o código: boa parte dos erros que parecem misteriosos no início é ambiente, não programação.
Fontes e leituras recomendadas
-
PHP — Instalação e configuração oficial https://www.php.net/manual/pt_BR/install.php Documentação oficial cobrindo instalação em todos os sistemas operacionais, com detalhes sobre extensões e configuração do
php.ini. -
Homebrew — Gerenciador de pacotes para macOS https://brew.sh Indispensável para desenvolvedores em macOS. Facilita a instalação e atualização do PHP e de centenas de outras ferramentas.
-
XAMPP — Apache Friends https://www.apachefriends.org Ambiente de desenvolvimento completo para Windows, macOS e Linux. Inclui PHP, Apache, MySQL e phpMyAdmin.
-
VS Code — Download oficial https://code.visualstudio.com Editor gratuito da Microsoft. Após instalar, busque "PHP Intelephense" na aba de extensões.
-
PHP Intelephense — Extensão VS Code https://marketplace.visualstudio.com/items?itemName=bmewburn.vscode-intelephense-client A extensão PHP mais completa para VS Code. Autocomplete preciso, detecção de erros em tempo real, navegação de código e muito mais.
-
PSR-12: Extended Coding Style https://www.php-fig.org/psr/psr-12/ O padrão oficial de estilo de código da comunidade PHP. Cobre indentação, espaçamento, nomenclatura e muito mais. Vale uma leitura rápida já nesta semana.
-
PhpStorm — JetBrains https://www.jetbrains.com/phpstorm/ IDE profissional para PHP. Considere quando avançar para os módulos de frameworks e projetos maiores.
Exercícios
Exercício 1
Seu projeto ficou pronto e alguém sugere: "sobe num servidor e deixa rodando php -S 0.0.0.0:80, já funciona". Por que isso não serve para produção?
Ver resposta
✓ Resposta: A própria documentação do PHP diz que o servidor embutido foi feito para auxiliar o desenvolvimento e não deve ser usado em rede pública. As razões são concretas. Ele atende uma requisição por vez por padrão: enquanto um usuário baixa uma imagem, todos os outros esperam — existe a variável PHP_CLI_SERVER_WORKERS para subir mais processos, mas ela é experimental e não resolve o resto. Ele não tem HTTPS, não tem limite de tamanho de requisição, não tem tempo de espera configurável, não faz balanceamento, não lida bem com conexão lenta (uma conexão deliberadamente arrastada trava o atendimento inteiro) e não trata arquivo estático com cache nem compressão. Também não há gerenciamento de processos: se o interpretador morre, ninguém o levanta de volta. Em produção o papel se divide: Nginx ou Apache na frente, cuidando de TLS, estáticos e conexões, e PHP-FPM atrás, com um pool de workers gerenciado, reinício automático e limites de memória e tempo por requisição. E há o detalhe que costuma escapar: rodar na porta 80 exige privilégio de root, e ninguém quer o interpretador que executa o código da aplicação rodando como root.
Exercício 2
O login funciona, mas o redirecionamento falha com Cannot modify header information — headers already sent by (output started at config.php:1). O config.php só tem duas linhas de código. Onde está o erro?
Ver resposta
✓ Resposta: O erro está no que você não vê no arquivo. A resposta HTTP tem cabeçalhos e corpo, nessa ordem, e o PHP envia os cabeçalhos na primeira vez que algo é impresso — depois disso, header(), setcookie() e session_start() chegam tarde demais. A mensagem entrega o culpado: output started at config.php:1, ou seja, alguma coisa foi impressa já na primeira linha. As duas causas clássicas são um espaço ou quebra de linha depois do ?> no fim do arquivo, que é texto e vai direto para a saída, e o BOM do UTF-8 — três bytes invisíveis que alguns editores gravam no início do arquivo, e que o PHP trata como conteúdo. Por isso a convenção existe: em arquivo que só tem PHP, omita o ?>; sem ele não há como sobrar espaço depois. Para o BOM, salve como "UTF-8 sem BOM" (no VS Code, o rodapé mostra a codificação e permite trocar). Um jeito rápido de flagrar: head -c 3 config.php | xxd — se aparecer efbbbf, é o BOM. E quando a origem não for óbvia, ligue display_errors em desenvolvimento: a própria mensagem nomeia o arquivo e a linha, e ela costuma ser ignorada justamente por parecer genérica.
Exercício 3
No terminal, php --version responde 8.4. No navegador, uma página com phpinfo() mostra 8.2. Qual é a explicação, e qual arquivo de configuração vale para cada uma?
Ver resposta
✓ Resposta: São duas instalações diferentes do PHP rodando na mesma máquina, e isso é o normal, não a exceção. O comando php usa a SAPI de linha de comando (CLI); a página no navegador é servida por outra SAPI — php-fpm atrás do Nginx, ou o módulo do Apache. Cada SAPI tem seu próprio binário, sua própria versão e, o que mais confunde, seu próprio php.ini: é comum haver /etc/php/8.4/cli/php.ini e /etc/php/8.2/fpm/php.ini lado a lado. Isso explica a queixa mais frequente de quem está começando: "instalei a extensão e continua dando erro" — instalou para a CLI, e quem precisava era o FPM. Para descobrir qual arquivo está em uso, php --ini mostra o da CLI, e o phpinfo() mostra o da web na linha Loaded Configuration File. Para saber quais versões existem, ls /etc/php/ no Debian e derivados, ou php -v comparado com a linha do topo do phpinfo(). E há um detalhe que economiza muito tempo: alterar o php.ini do FPM só tem efeito depois de reiniciar o serviço (sudo systemctl restart php8.2-fpm), enquanto na CLI o novo valor vale já na próxima execução — a diferença faz parecer que a alteração "não pegou".
Exercício 4
Ao rodar o projeto aparece Fatal error: Uncaught Error: Call to undefined function mb_strlen(). Descreva o diagnóstico, do sintoma até a correção.
Ver resposta
✓ Resposta: "Função indefinida" com nome de função nativa quer dizer, quase sempre, extensão ausente — não erro de digitação nem de versão. O prefixo mb_ pertence à mbstring, que é uma extensão separada e não vem habilitada em toda instalação. O diagnóstico tem três passos. Primeiro, confirme: php -m | grep mbstring lista as extensões carregadas na CLI; se não aparecer, está fora. Segundo, instale para a versão certa — sudo apt install php8.4-mbstring no Debian e derivados, ou descomente extension=mbstring no php.ini no Windows, onde ela vem junto mas desligada. Terceiro, e é onde a maioria tropeça: reinicie o FPM se o erro aparece pelo navegador, porque o processo já carregou a configuração antiga. Um cuidado extra: conferir na mesma SAPI em que o erro ocorreu. Se o erro é na web, php -m no terminal pode mostrar a extensão presente e ainda assim faltar no FPM — nesse caso use php-fpm8.4 -m ou olhe o phpinfo(). Para evitar a surpresa no deploy, declare as extensões no composer.json, em require ("ext-mbstring": "*"): aí o composer install falha no servidor errado antes de a aplicação falhar no ar.
Exercício 5
Desafio: o sistema funciona na sua máquina e quebra no servidor do cliente. Liste o que precisa estar igual nos dois lugares para que "funciona na minha máquina" deixe de ser uma frase possível — e como você verificaria cada item.
Ver resposta
✓ Resposta: São cinco frentes, e nenhuma delas é o código. A primeira é a versão do PHP: fixe-a no composer.json em config.platform.php, para que o Composer resolva as dependências pela versão do servidor e não pela sua, e compare com php -v nos dois lados. A segunda são as extensões: php -m em cada máquina, e a diferença declarada como ext-* no require. A terceira é o php.ini, onde moram as armadilhas silenciosas — memory_limit, upload_max_filesize e post_max_size (que precisam subir juntos, e o menor vence), max_execution_time, date.timezone e, acima de tudo, display_errors: ligado na sua máquina e desligado no servidor, o mesmo erro vira tela branca, e a impressão é de que "só lá quebra" quando na verdade só lá o erro fica invisível. Ligue log_errors e leia o log em vez de adivinhar. A quarta é o sistema de arquivos: Linux diferencia maiúsculas de minúsculas e Windows e macOS não, então require 'Models/Usuario.php' funciona na sua máquina e falha no servidor — é o defeito que mais se disfarça de mistério. A quinta são permissões e caminhos: o usuário do FPM (www-data) precisa poder escrever nas pastas de cache e upload, e caminho absoluto colado do seu computador não existe lá. A forma de eliminar a frase de vez, porém, não é conferir item por item: é reproduzir o ambiente — um contêiner com a mesma imagem do PHP em desenvolvimento e em produção transforma a maioria desses cinco itens em uma linha de configuração versionada junto do código.