PHP MySQLi
Aprenda a extensão PHP MySQLi: conecte ao MySQL, execute consultas com segurança usando prepared statements e compare MySQLi com PDO.
MySQLi ("MySQL Improved") é a extensão PHP utilizada para conectar a um banco de dados MySQL ou MariaDB, executar consultas e ler os resultados. Este artigo explica o que é a extensão, como conectar, como executar consultas SELECT/INSERT/UPDATE com segurança e quando usar MySQLi em vez de PDO.
O que é a extensão MySQLi?
A extensão MySQLi é a sucessora das antigas funções mysql_* (agora removidas). Ela adiciona recursos que a extensão original nunca teve: prepared statements, transações, múltiplas instruções e suporte adequado à autenticação do MySQL 4.1+. Ela acompanha o PHP e está habilitada por padrão na maioria das instalações.
O MySQLi expõe a mesma funcionalidade por meio de duas interfaces:
- Orientada a objetos — você trabalha com um objeto
mysqlie chama métodos como$mysqli->query(). Este é o estilo que a maioria dos códigos modernos usa, e o que este artigo segue. - Procedural — você chama funções como
mysqli_connect()emysqli_query()e passa a conexão como primeiro argumento.
Ambas fazem exatamente a mesma coisa; escolha uma e seja consistente. A forma orientada a objetos é mais curta e mais legível.
Conectando a um banco de dados
Uma conexão é representada por um objeto mysqli. Você cria um passando o host, nome de usuário, senha e nome do banco de dados ao construtor e, em seguida, verifica se a conexão foi bem-sucedida antes de fazer qualquer outra coisa:
<?php
$mysqli = new mysqli("localhost", "username", "password", "my_database");
// Always check the connection before using it.
if ($mysqli->connect_error) {
die("Failed to connect to MySQL: " . $mysqli->connect_error);
}
// Recommended: use UTF-8 so accented characters and emoji are stored correctly.
$mysqli->set_charset("utf8mb4");
echo "Connected successfully";
?>A propriedade connect_error contém uma mensagem legível quando a conexão falha (ou null em caso de sucesso). Chamar set_charset() logo após a conexão evita problemas sutis de codificação mais adiante. Para uma visão mais detalhada sobre como abrir uma conexão, consulte PHP mysqli_connect() e a referência de connect().
Executando uma consulta SELECT
Uma vez conectado, query() executa SQL e retorna um objeto de resultado sobre o qual você pode iterar. fetch_assoc() retorna uma linha por vez como um array associativo, ou null quando não há mais linhas:
<?php
$result = $mysqli->query("SELECT name, email FROM users");
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
echo "Name: " . $row["name"] . " - Email: " . $row["email"] . "<br>";
}
} else {
echo "No users found.";
}
$result->free(); // release the result set
$mysqli->close(); // close the connection when you are done
?>num_rows informa quantas linhas foram retornadas, para que você possa exibir uma mensagem amigável quando uma consulta não retornar nada. Consulte PHP MySQL Select Data para mais padrões de consulta.
Prepared statements (a forma segura de usar entradas)
Nunca insira dados do usuário diretamente em uma string de consulta — é assim que ocorre a injeção de SQL. Um prepared statement envia o SQL e os dados separadamente, de modo que o banco de dados trata a entrada estritamente como um valor e nunca como SQL executável.
Você escreve marcadores ?, usa prepare() para preparar a instrução e depois bind_param() para os valores reais:
<?php
$age = 18;
$stmt = $mysqli->prepare("SELECT name, email FROM users WHERE age > ?");
$stmt->bind_param("i", $age); // "i" = integer (s = string, d = double, b = blob)
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo "Name: " . $row["name"] . " - Email: " . $row["email"] . "<br>";
}
$stmt->close();
?>O primeiro argumento de bind_param() é uma string de tipos: um caractere por marcador — i (inteiro), s (string), d (double/float) ou b (blob). Os demais argumentos são os valores, em ordem.
Nota:
get_result()requer o drivermysqlnd, que é o padrão no PHP moderno. Se a sua instalação não o possui, usebind_result()para vincular colunas a variáveis.
Para um tutorial dedicado, consulte PHP MySQL Prepared Statements.
Inserindo e atualizando dados
O mesmo padrão de prepared statement funciona para gravações. Após um INSERT, o id de auto-incremento da nova linha está disponível em $mysqli->insert_id; após um INSERT/UPDATE/DELETE, $mysqli->affected_rows informa quantas linhas foram alteradas:
<?php
$name = "Ada Lovelace";
$email = "[email protected]";
$stmt = $mysqli->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->bind_param("ss", $name, $email); // two strings
$stmt->execute();
echo "Inserted user #" . $mysqli->insert_id;
$stmt->close();
?>Consulte PHP MySQL Insert Data e PHP MySQL Update Data para o quadro completo de CRUD.
Tratando erros
Se uma consulta falhar, query() retorna false e os detalhes ficam no objeto de conexão. Ler $mysqli->error após uma chamada com falha informa o que deu errado:
<?php
if (!$mysqli->query("SELECT * FROM no_such_table")) {
echo "Query failed (" . $mysqli->errno . "): " . $mysqli->error;
}
?>Em desenvolvimento, você pode fazer o MySQLi lançar exceções automaticamente com mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT), que é o comportamento padrão desde o PHP 8.1. Leitura relacionada: PHP connect_error e PHP connect_errno.
MySQLi vs. PDO — qual devo usar?
Ambos são formas seguras e modernas de comunicar com um banco de dados. Em resumo:
- MySQLi funciona apenas com MySQL/MariaDB. Ele expõe alguns recursos específicos do MySQL (como consultas assíncronas) que o PDO não oferece.
- PDO (PHP Data Objects) suporta uma dúzia de bancos de dados por meio de uma única API, de modo que mudar do MySQL para o PostgreSQL significa alterar uma string de conexão, não as suas consultas. Ele também suporta marcadores nomeados (
:name), mais fáceis de ler.
Se você sabe que usará apenas MySQL, o MySQLi é perfeitamente adequado. Se a portabilidade é importante, prefira o PDO. De qualquer forma, sempre use prepared statements.
Resumo
- MySQLi é a extensão padrão para trabalhar com MySQL/MariaDB em PHP, disponível nos estilos orientado a objetos e procedural.
- Crie uma conexão com
new mysqli(...), verifiqueconnect_errore defina o charset. - Use
query()+fetch_assoc()para ler dados e iterar sobre os resultados. - Use prepared statements (
prepare()→bind_param()→execute()) para qualquer coisa que envolva entrada do usuário, para se manter seguro contra injeção de SQL. - Verifique
$mysqli->error/$mysqli->errnoquando uma consulta falhar e prefira o PDO quando precisar de portabilidade de banco de dados.