W3docs

real_escape_string

Saiba como usar mysqli_real_escape_string() em PHP para escapar caracteres especiais em strings usadas em consultas SQL e evitar injeção SQL.

A função mysqli_real_escape_string() escapa caracteres especiais em uma string para que ela possa ser inserida com segurança em uma consulta SQL. Esta página explica o que a função faz, sua sintaxe e valor de retorno, o problema de charset que a quebra, a função obsoleta mysql_real_escape_string() que ela substituiu, e por que as instruções preparadas são a melhor escolha hoje.

O que mysqli_real_escape_string() faz

Quando você constrói uma consulta SQL concatenando diretamente a entrada do usuário na string da consulta, um valor como O'Reilly encerra a string entre aspas prematuramente e o restante é tratado como SQL. Um invasor pode explorar isso para ler, modificar ou excluir dados — um ataque de injeção SQL.

mysqli_real_escape_string() evita isso adicionando barras invertidas antes dos caracteres que têm significado especial dentro de um literal de string MySQL: aspas simples ', aspas duplas ", barra invertida \, byte NUL, nova linha \n, retorno de carro \r e Ctrl+Z. Após o escape, o valor é seguro para ser incorporado entre aspas em uma consulta.

É "real" porque consulta o conjunto de caracteres da conexão, portanto escapa corretamente mesmo para codificações multibyte — algo que a função mais antiga addslashes() não consegue fazer.

Sintaxe

mysqli_real_escape_string(mysqli $connection, string $string): string
ParâmetroDescrição
$connectionUm link retornado por mysqli_connect(). A função precisa dele para conhecer o charset da conexão.
$stringA string a ser escapada.

Ela retorna a string escapada. Observe que ela não adiciona as aspas ao redor — você ainda escreve '$escaped' na consulta por conta própria.

No estilo orientado a objetos, chame-a como um método: $mysqli->real_escape_string($string).

Como usar

<?php
$con = mysqli_connect('localhost', 'username', 'password', 'database');

if (!$con) {
    exit('Could not connect: ' . mysqli_error($con));
}

// Set charset to prevent multi-byte character vulnerabilities
mysqli_set_charset($con, 'utf8mb4');

$name = "John O'Reilly";
$name = mysqli_real_escape_string($con, $name);

$sql = "INSERT INTO customers (name) VALUES ('$name')";

if (!mysqli_query($con, $sql)) {
    exit('Error: ' . mysqli_error($con));
}

echo '1 record added';

mysqli_close($con);
?>

Aqui nos conectamos com mysqli_connect(), definimos $name com uma aspa simples e o escapamos. O valor escapado John O\'Reilly encaixa-se com segurança no marcador '$name', então o INSERT é executado sem erro de sintaxe e sem abrir uma brecha de injeção. Consulte Inserir dados no MySQL para o fluxo completo de inserção.

Defina o charset primeiro

mysqli_real_escape_string() só escapa corretamente se a conexão conhece seu conjunto de caracteres. Sempre chame mysqli_set_charset() logo após conectar:

mysqli_set_charset($con, 'utf8mb4');

Ignorar isso em certas codificações (especialmente GBK) deixa um vetor de injeção multibyte onde a barra invertida de escape é "engolida" por uma sequência multibyte. Definir o charset na conexão — não apenas na consulta — fecha essa brecha.

O que ele não protege

O escape torna um valor seguro dentro de um literal de string entre aspas. Ele não torna os valores seguros em lugares onde você não pode usar aspas — nomes de tabelas e colunas, números de LIMIT ou palavras-chave. Nunca escape um identificador e o insira em uma consulta; valide-o contra uma lista de permissões.

// WRONG — escaping does nothing useful for an identifier
$column = mysqli_real_escape_string($con, $_GET['sort']);
$sql = "SELECT * FROM users ORDER BY $column"; // still injectable

// RIGHT — allow-list
$allowed = ['name', 'email', 'created_at'];
$column  = in_array($_GET['sort'], $allowed, true) ? $_GET['sort'] : 'name';

mysql_real_escape_string() vs mysqli_real_escape_string()

A antiga mysql_real_escape_string() (sem o i) pertencia à extensão mysql_* original, que foi removida no PHP 7. Use a versão mysqli_* — ou PDO — em qualquer PHP moderno. Se você a chamar sem uma conexão ativa, ela abre silenciosamente uma padrão e emite um aviso, o que é mais um motivo pelo qual foi descontinuada.

Prefira instruções preparadas

O escape funciona, mas depende de você nunca esquecer um único valor. As instruções preparadas são mais seguras porque o modelo de consulta e os dados trafegam separadamente, portanto a entrada do usuário nunca pode alterar a estrutura da consulta:

<?php
$con = mysqli_connect('localhost', 'username', 'password', 'database');
mysqli_set_charset($con, 'utf8mb4');

$stmt = mysqli_prepare($con, 'INSERT INTO customers (name) VALUES (?)');
mysqli_stmt_bind_param($stmt, 's', $name);

$name = "John O'Reilly"; // no manual escaping needed
mysqli_stmt_execute($stmt);

echo '1 record added';
mysqli_close($con);
?>

Use mysqli_real_escape_string() quando realmente precisar construir SQL dinâmico manualmente; prefira mysqli_prepare() no restante do tempo. Para uma visão geral da extensão, consulte PHP MySQLi.

Conclusão

mysqli_real_escape_string() escapa os caracteres especiais que, de outra forma, quebrariam — ou seriam explorados em — um literal de string SQL. Defina o charset da conexão primeiro, lembre-se de que ela não faz nada para identificadores e prefira instruções preparadas sempre que possível.

Prática

Prática
O que a função PHP mysql_real_escape_string faz?
O que a função PHP mysql_real_escape_string faz?
Was this page helpful?