PHP e AJAX
Aprenda a combinar PHP AJAX para criar aplicações web dinâmicas e responsivas, com exemplos práticos de busca ao vivo e validação de formulários.
Este capítulo explica como combinar AJAX (no navegador) com PHP (no servidor) para que uma página possa se comunicar com o servidor em segundo plano e atualizar apenas a parte que mudou — sem recarregamento completo. Você irá construir um exemplo completo e funcional, ver como ler a requisição em PHP e retornar JSON, e aprender as regras de segurança e tratamento de erros que aplicações reais precisam.
O que é PHP AJAX?
AJAX significa Asynchronous JavaScript and XML. Apesar do nome, o AJAX moderno raramente usa XML — ele envia e recebe JSON, porque JSON mapeia diretamente para objetos JavaScript e arrays PHP. A palavra-chave é assíncrono: o navegador dispara uma requisição e continua executando. Quando o servidor responde, um callback atualiza a página. O usuário nunca vê uma tela em branco recarregando.
"PHP AJAX" é apenas esse padrão com PHP como lado servidor: JavaScript envia a requisição, um script PHP a processa (frequentemente consultando um banco de dados), e PHP retorna JSON para JavaScript renderizar.
Usos comuns:
- Busca ao vivo / autocomplete — sugestões aparecem conforme você digita.
- Validação de formulário inline — verificar um nome de usuário ou e-mail antes de o usuário enviar.
- Botões de curtir / votar / favoritar — atualizar um contador sem sair da página.
- Scroll infinito e "carregar mais" — buscar a próxima página de resultados sob demanda.
Como uma requisição AJAX flui
Uma única ida e volta sempre segue os mesmos quatro passos:
- Evento — o usuário digita, clica ou envia. JavaScript captura o evento.
- Requisição — JavaScript envia uma requisição HTTP para um endpoint PHP (com
fetchouXMLHttpRequest). - Trabalho no servidor — PHP lê a entrada de
$_GET,$_POSTou do corpo bruto da requisição, faz seu trabalho (por exemplo, uma consulta ao banco de dados) eechos uma resposta JSON. - Atualização — JavaScript recebe o JSON, analisa-o e atualiza o DOM.
O navegador é o cliente; o script PHP é o servidor. Eles apenas trocam pequenos pedaços de dados, por isso o AJAX parece instantâneo comparado ao recarregamento de uma página inteira.
Enviando a requisição: fetch vs XMLHttpRequest
XMLHttpRequest (XHR) é a API AJAX original. fetch é o substituto moderno baseado em promessas — mais curto, mais fácil de ler e integrado em todos os navegadores atuais. Use fetch para código novo; você só precisa do XHR ao suportar navegadores muito antigos.
// Modern: fetch returns a Promise
fetch('endpoint.php')
.then(res => res.json()) // parse the JSON body
.then(data => console.log(data));
// Legacy: the equivalent with XMLHttpRequest
const xhr = new XMLHttpRequest();
xhr.open('GET', 'endpoint.php');
xhr.onload = () => console.log(JSON.parse(xhr.responseText));
xhr.send();Lendo a requisição e respondendo com JSON em PHP
Como PHP lê os dados recebidos depende de como JavaScript os enviou:
| JavaScript envia | PHP lê com |
|---|---|
String de consulta URL (?q=...) | $_GET['q'] |
FormData (um formulário real) | $_POST['field'] |
Corpo JSON.stringify(obj) | json_decode(file_get_contents('php://input'), true) |
Qualquer que seja a entrada, a resposta deve ser JSON com o cabeçalho correto para que o navegador a analise corretamente:
<?php
header('Content-Type: application/json');
echo json_encode(['status' => 'success', 'value' => 42]);A linha header() informa ao navegador que o corpo é JSON. json_encode() transforma o array PHP em uma string JSON. Veja PHP JSON e json_encode() para a referência completa.
Um exemplo completo: sugestões de busca ao vivo
Este é um autocomplete completo e funcional: digite na caixa, JavaScript consulta search.php, e PHP retorna itens correspondentes como JSON.
HTML + JavaScript (a página):
<input id="searchInput" type="text" placeholder="Search fruit…" autocomplete="off">
<ul id="results"></ul>
<script>
const input = document.getElementById('searchInput');
const list = document.getElementById('results');
let timer;
input.addEventListener('input', () => {
// Debounce: wait until the user pauses typing (avoids a request per keystroke)
clearTimeout(timer);
timer = setTimeout(() => {
const query = input.value.trim();
if (!query) { list.innerHTML = ''; return; }
fetch(`search.php?q=${encodeURIComponent(query)}`)
.then(res => res.json())
.then(data => {
list.innerHTML = data.suggestions
.map(item => `<li>${item}</li>`)
.join('');
})
.catch(() => { list.innerHTML = '<li>Search failed</li>'; });
}, 250);
});
</script>PHP (search.php):
<?php
header('Content-Type: application/json');
// 1. Read and sanitise the input
$query = trim($_GET['q'] ?? '');
// 2. Do the work. In real code this is a *prepared* SQL query — see the note below.
$fruits = ['apple', 'apricot', 'banana', 'cherry', 'grape', 'mango'];
$matches = array_values(array_filter(
$fruits,
fn($fruit) => str_contains($fruit, strtolower($query))
));
// 3. Reply with JSON
echo json_encode(['suggestions' => $matches]);Digite ap e a lista mostra todas as frutas que contêm essas letras — apple, apricot e grape — e a página nunca recarrega. Para buscar sugestões de um banco de dados em vez do array em memória, use um prepared statement como mostrado em AJAX e Banco de Dados MySQL.
Sempre use prepared statements. Nunca insira
$_GET['q']diretamente em uma string SQL — isso é uma brecha de SQL injection. Use parâmetros vinculados (veja PHP MySQLi).
Validação de formulário inline
Valide um campo no servidor antes de o usuário enviar o formulário inteiro. As mesmas regras PHP que protegem o envio podem ser reutilizadas para a verificação AJAX.
const form = document.getElementById('myForm');
form.addEventListener('submit', (e) => {
e.preventDefault(); // stop the normal page reload
fetch('validate.php', {
method: 'POST',
body: new FormData(form) // sends fields as $_POST
})
.then(res => res.json())
.then(data => {
if (data.valid) form.submit();
else console.log(data.errors);
});
});<?php
header('Content-Type: application/json');
$errors = [];
$email = trim($_POST['email'] ?? '');
if ($email === '') {
$errors[] = 'Email is required';
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = 'Invalid email format';
}
echo json_encode(['valid' => empty($errors), 'errors' => $errors]);new FormData(form) coleta todos os campos, então PHP os lê de $_POST. Para uma cobertura mais aprofundada de formulários, veja PHP Form Validation e PHP $_GET / $_POST superglobals.
Erros comuns
- CORS. Uma requisição para uma origem diferente (domínio, porta ou esquema) é bloqueada a menos que o servidor PHP envie
Access-Control-Allow-Origin. Requisições de mesma origem não precisam de nada. - Defina o cabeçalho JSON. Esquecer
header('Content-Type: application/json')ainda funciona comres.json(), mas quebra ferramentas que dependem do tipo de conteúdo. Sempre defina-o. - Trate erros. Falhas de rede e respostas 500 devem ser capturadas — adicione um
.catch()e verifiqueres.ok, ou a interface silenciosamente não faz nada. - Faça debounce em requisições ao vivo. Sem o debounce com
setTimeoutacima, cada pressionamento de tecla dispara uma requisição e sobrecarrega o servidor. - Escape a saída que você injeta no DOM. Inserir texto bruto do servidor com
innerHTMLpode introduzir XSS; escape ou usetextContentpara dados não confiáveis.
Resumo
PHP AJAX permite que uma página troque pequenas quantidades de dados com o servidor em segundo plano e atualize no lugar. JavaScript envia a requisição com fetch, PHP a lê de $_GET/$_POST/php://input, faz seu trabalho e retorna JSON via json_encode(). Mantenha a entrada com prepared statements, defina o cabeçalho JSON e sempre trate o caminho de erro.
Próximos passos: conecte AJAX a um banco de dados real em AJAX e MySQL, e aprenda o formato de resposta em profundidade em PHP JSON.