The 4th Annual China PHP Conference


(PHP 4 >= 4.3.0, PHP 5)

mysql_real_escape_stringProtège une commande SQL de la présence de caractères spéciaux


Cette extension était obsolète en PHP 5.5.0, et a été supprimée en PHP 7.0.0. À la place, vous pouvez utiliser l'extension MySQLi ou l'extension PDO_MySQL. Voir aussi MySQL : choisir une API du guide et ces entrées de la FAQ pour plus d'informations. Alternatives à cette fonction :


string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier = NULL ] )

mysql_real_escape_string() protège une commande SQL de la chaîne unescaped_string, en "échappant" les caractères spéciaux tout en prenant en compte le jeu de caractères courant de la connexion link_identifier. Le résultat peut être utilisé sans problème avec la fonction mysql_query(). Si des données binaires doivent être insérées, cette fonction doit être utilisée.

mysql_real_escape_string() appelle la fonction mysql_escape_string() de la bibliothèque MySQL qui ajoute un anti-slash aux caractères suivants : NULL, \x00, \n, \r, \, ', " et \x1a.

Cette fonction doit toujours (avec quelques exceptions) être utilisée avant d'envoyer la requête à MySQL afin de protéger vos données d'injection de caractères pouvant dévoyer cette requête.


Securité : le jeu de caractères par défaut

Le jeu de caractèrs doit être défini soit au niveau serveur, soit avec la fonction API mysql_set_charset() pour qu'il ait un effet sur la fonction mysql_real_escape_string(). Voir la section sur les concepts on des jeux de caractères pour plus d'informations.

Liste de paramètres


La chaîne à échapper.


La connexion MySQL. S'il n'est pas spécifié, la dernière connexion ouverte avec la fonction mysql_connect() sera utilisée. Si une telle connexion n'est pas trouvée, la fonction tentera d'ouvrir une connexion, comme si la fonction mysql_connect() avait été appelée sans argument. Si aucune connexion n'est trouvée ou établie, une alerte E_WARNING est générée.

Valeurs de retour

Retourne la chaîne échappée, ou FALSE si une erreur survient.


Exemple #1 Exemple simple avec mysql_real_escape_string()

// Connexion
$link mysql_connect('mysql_host''mysql_user''mysql_password')
OR die(

// Requête
$query sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",

Exemple #2 Un exemple d'attaque par injection SQL

// Nous ne vérifions pas $_POST['password'], il peut contenir ce que l'utilisateur veut ! Par exemple :
$_POST['username'] = 'aidan';
$_POST['password'] = "' OR ''='";

// Demande à la base de vérifier si un utilisateur correspond
$query "SELECT * FROM users WHERE user='{$_POST['username']}' AND password='{$_POST['password']}'";

// Cela signifie que la requête envoyée à MySQL sera :
echo $query;

La requête envoyée à MySQL :

SELECT * FROM users WHERE user='aidan' AND password='' OR ''=''

Cela permet à n'importe qui de s'identifier sans mot de passe valide.



Une connexion MySQL est nécessaire avant d'utiliser la fonction mysql_real_escape_string(), sinon, une erreur de niveau E_WARNING sera générée, et FALSE sera retourné. Si link_identifier n'est pas défini, la dernière connexion MySQL est utilisée.


Si magic_quotes_gpc est activée, appliquez d'abord la fonction stripslashes() à vos données. Utiliser cette fonction sur des données qui ont déjà été protégées, les protégera une deuxième fois.


Si cette fonction n'est pas utilisée pour protéger vos données, la requête sera vulnérable aux attaques par injection SQL.

Note: mysql_real_escape_string() n'échappe ni %, ni _. Ce sont des jokers en MySQL si combinés avec LIKE, GRANT, ou REVOKE.

Voir aussi

add a note add a note

User Contributed Notes 7 notes

5 years ago
Just a little function which mimics the original mysql_real_escape_string but which doesn't need an active mysql connection. Could be implemented as a static function in a database class. Hope it helps someone.

function mysql_escape_mimic($inp) {
array_map(__METHOD__, $inp);

$inp) && is_string($inp)) {
str_replace(array('\\', "\0", "\n", "\r", "'", '"', "\x1a"), array('\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z'), $inp);

Walter Tross
4 years ago
For further information:
(replace your MySQL version in the URL)
10 years ago
Note that mysql_real_escape_string doesn't prepend backslashes to \x00, \n, \r, and and \x1a as mentionned in the documentation, but actually replaces the character with a MySQL acceptable representation for queries (e.g. \n is replaced with the '\n' litteral). (\, ', and " are escaped as documented) This doesn't change how you should use this function, but I think it's good to know.
sam at numbsafari dot com
3 years ago
No discussion of escaping is complete without telling everyone that you should basically never use external input to generate interpreted code. This goes for SQL statements, or anything you would call any sort of "eval" function on.

So, instead of using this terribly broken function, use parametric prepared statements instead.

Honestly, using user provided data to compose SQL statements should be considered professional negligence and you should be held accountable by your employer or client for not using parametric prepared statements.

What does that mean?

It means instead of building a SQL statement like this:


You should use mysqli's prepare() function ( to execute a statement that looks like this:


NB: This doesn't mean you should never generate dynamic SQL statements. What it means is that you should never use user-provided data to generate those statements. Any user-provided data should be passed through as parameters to the statement after it has been prepared.

So, for example, if you are building up a little framework and want to do an insert to a table based on the request URI, it's in your best interest to not take the $_SERVER['REQUEST_URI'] value (or any part of it) and directly concatenate that with your query. Instead,  you should parse out the portion of the $_SERVER['REQUEST_URI'] value that you want, and map that through some kind of function or associative array to a non-user provided value. If the mapping produces no value, you know that something is wrong with the user provided data.

Failing to follow this has been the cause of a number of SQL-injection problems in the Ruby On Rails framework, even though it uses parametric prepared statements. This is how GitHub was hacked at one point. So, no language is immune to this problem. That's why this is a general best practice and not something specific to PHP and why you should REALLY adopt it.

Also, you should still do some kind of validation of the data provided by users, even when using parametric prepared statements. This is because that user-provided data will often become part of some generated HTML, and you want to ensure that the user provided data isn't going to cause security problems in the browser.
strata_ranger at hotmail dot com
6 years ago
There's an interesting quirk in the example #2 about SQL injection:  AND takes priority over OR, so the injected query actually executes as WHERE (user='aidan' AND password='') OR ''='', so instead of returning a database record corresponding to an arbitrary username (in this case 'aidan'), it would actually return ALL database records.  In no particular order.  So an attacker might be able to log in as any account, but not necessarily with any control over which account it is.

Of course a potential attacker could simply modify their parameters to target specific users of interest:


// E.g. attacker's values
$_POST['username'] = '';
$_POST['password'] = "' OR user = 'administrator' AND '' = '";

// Malformed query
$query = "SELECT * FROM users WHERE user='$_POST[username]' AND password='$_POST[password]'";


// The query sent to MySQL would read:
// SELECT * FROM users WHERE user='' AND password='' OR user='administrator' AND ''='';
// which would allow anyone to gain access to the account named 'administrator'

plgs at ozemail dot com dot au
6 years ago
Don't forget that if you're using Mysqli (ie, the "improved" Mysql extension) then you need to use the corresponding mysqli function mysqli_real_escape_string().  The parameter order is also different.
presto dot dk at gmail dot com
6 years ago
If you want to make sure that the ID you're using to do a query is a number, use sprint() of (int) or intval(), but don't use mysql_real_escape_string.

There is no difference between ISO-8859-1's number 10 and UTF-8's number 10.
To Top