PHP MySQL Select: Um Guia Completo
Aprenda a usar SELECT em PHP — filtre com WHERE, ordene com ORDER BY, pagine com LIMIT e busque linhas com mysqli e PDO.
SELECT é a instrução SQL que lê dados de um banco de dados — é a que você mais usará. Este guia aborda a sintaxe do SELECT, as cláusulas que moldam seus resultados e as duas extensões PHP (mysqli e PDO) que você usa para executar uma consulta e percorrer as linhas retornadas.
Se você ainda não se conectou a um banco de dados, comece com PHP MySQL Connect; para inserir linhas em uma tabela primeiro, veja PHP MySQL Insert.
O Que a Instrução SELECT Faz
SELECT recupera linhas de uma ou mais tabelas. Na forma mais simples, você nomeia as colunas que deseja e a tabela da qual lê:
SELECT column1, column2, ...
FROM table_name;Use * para selecionar todas as colunas. É conveniente para exploração rápida, mas você deve nomear as colunas explicitamente no código da aplicação — é mais rápido, deixa sua intenção clara e seu código não quebrará quando alguém adicionar uma coluna à tabela.
-- All columns (fine for the mysql console, avoid in app code)
SELECT * FROM users;
-- Only what you need (preferred)
SELECT id, name, email FROM users;Um SELECT sempre retorna um conjunto de resultados: zero ou mais linhas, cada uma composta pelas colunas que você solicitou. O PHP fornece esse conjunto de resultados como algo que você pode percorrer.
Moldando o Conjunto de Resultados
A forma de colunas e tabela é apenas o começo. Cinco cláusulas permitem filtrar, ordenar, agrupar e combinar dados. Elas devem aparecer nesta ordem quando você usar mais de uma:
| Cláusula | O que faz | Aprofundamento |
|---|---|---|
WHERE | Mantém apenas as linhas que correspondem a uma condição | MySQL WHERE |
GROUP BY | Agrupa linhas para agregações como COUNT() | — |
HAVING | Filtra esses grupos (como WHERE, mas para agregações) | — |
ORDER BY | Ordena as linhas | MySQL ORDER BY |
LIMIT | Limita a quantidade de linhas retornadas | MySQL LIMIT |
Filtrando com WHERE
Retornar apenas os usuários chamados John:
SELECT name, email
FROM users
WHERE name = 'John';Ordenando com ORDER BY
Ordenar alfabeticamente pelo nome. ASC é crescente (o padrão), DESC é decrescente:
SELECT name, email
FROM users
ORDER BY name ASC;Limitando linhas com LIMIT
Buscar apenas os 10 usuários mais recentes — essencial para paginação e para não carregar um milhão de linhas na memória:
SELECT name, email
FROM users
ORDER BY created_at DESC
LIMIT 10;Unindo tabelas
JOIN une tabelas relacionadas por uma chave compartilhada. Aqui cada pedido é associado ao usuário que o fez:
SELECT users.name, orders.order_id
FROM users
JOIN orders ON users.id = orders.user_id;Executando um SELECT a Partir do PHP
Para obter dados no seu código PHP, o fluxo é sempre o mesmo:
- Conectar ao banco de dados.
- Executar a instrução
SELECT. - Buscar as linhas do conjunto de resultados.
- Fechar a conexão (o PHP também a fecha automaticamente ao final da requisição).
Sempre use instruções preparadas para entrada do usuário
Nunca insira uma variável diretamente em uma string de consulta. Se $name vem de um formulário, um atacante pode injetar SQL e ler ou destruir todo o seu banco de dados:
// DANGER: SQL injection. Never do this with untrusted input.
$result = $conn->query("SELECT name, email FROM users WHERE name = '$name'");Uma instrução preparada envia a consulta e os dados separadamente, para que o valor nunca possa ser interpretado como SQL. Este é o hábito mais importante ao ler dados fornecidos pelo usuário. Veja MySQL Prepared Statements para mais informações.
Com mysqli
$conn = mysqli_connect("localhost", "username", "password", "database");
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
$stmt = $conn->prepare("SELECT name, email FROM users WHERE name = ?");
$name = "John";
$stmt->bind_param("s", $name); // "s" = the parameter is a string
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
echo "Name: " . $row["name"] . " - Email: " . $row["email"] . "<br>";
}
} else {
echo "0 results";
}
$stmt->close();
mysqli_close($conn);fetch_assoc() retorna cada linha como um array associativo indexado pelo nome da coluna ($row["name"]). Use fetch_array() se também quiser chaves numéricas, ou fetch_all(MYSQLI_ASSOC) para buscar todas as linhas de uma vez em um array.
Com PDO
Para novos projetos, PDO é geralmente a melhor escolha: possui uma API consistente para MySQL, PostgreSQL, SQLite e outros, e suas instruções preparadas são fáceis de ler.
$pdo = new PDO("mysql:host=localhost;dbname=database;charset=utf8mb4", "username", "password");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare("SELECT name, email FROM users WHERE name = ?");
$stmt->execute(["John"]);
foreach ($stmt as $row) {
echo "Name: " . $row["name"] . " - Email: " . $row["email"] . "<br>";
}Definir PDO::ERRMODE_EXCEPTION faz com que consultas com falha lancem exceções em vez de falhar silenciosamente — envolva as chamadas ao banco de dados em try/catch para que os problemas apareçam em vez de desaparecerem.
Erros Comuns
num_rowsretorna linhas, não um boolean. Verifique> 0(mysqli) antes de assumir que obteve dados.- Selecionar
*e depois ler apenas uma coluna ainda transfere todas as colunas pela rede. Selecione apenas o que você usa. - Esquecer o
LIMITem tabelas grandes pode carregar enormes conjuntos de resultados na memória. Pagine. - A comparação de strings no
WHEREnão diferencia maiúsculas de minúsculas por padrão nas collations comuns do MySQL —'john'corresponde a'John'.
Conclusão
SELECT é a base de toda aplicação PHP/MySQL. Nomeie suas colunas explicitamente, molde os resultados com WHERE, ORDER BY, LIMIT e JOIN, e sempre leia a entrada do usuário por meio de instruções preparadas (mysqli ou PDO) para se proteger de injeção SQL. A partir daqui, aprenda a modificar dados com MySQL Insert e MySQL Update.