(PHP 4 >= 4.3.0, PHP 5)
mysql_real_escape_string —Escapes special characters in a string for use in an SQL statement
This extension was deprecated in PHP 5.5.0, and it was removed in PHP 7.0.0.Instead, theMySQLi orPDO_MySQL extension should be used.See alsoMySQL: choosing an API guide.Alternatives to this function include:
Escapes special characters in theunescaped_string, taking into account the current character set of the connection so that it is safe to place it in amysql_query(). If binary data is to be inserted, this function must be used.
mysql_real_escape_string() calls MySQL's library function mysql_real_escape_string, which prepends backslashes to the following characters:\x00,\n,\r,\,'," and\x1a.
This function must always (with few exceptions) be used to make data safe before sending a query to MySQL.
The character set must be set either at the server level, or with the API functionmysql_set_charset() for it to affectmysql_real_escape_string(). See the concepts section oncharacter sets for more information.
unescaped_stringThe string that is to be escaped.
link_identifierThe MySQL connection. If thelink identifier is not specified, the last link opened bymysql_connect() is assumed. If no such link is found, itwill try to create one as ifmysql_connect() had been calledwith no arguments. If no connection is found or established, anE_WARNING level error is generated.
Returns the escaped string, orfalse on error.
Executing this function without a MySQL connection present will also emitE_WARNING level PHP errors. Only execute this function with a valid MySQL connection present.
Example #1 Simplemysql_real_escape_string() example
<?php
// Connect
$link=mysql_connect('mysql_host','mysql_user','mysql_password')
OR die(mysql_error());
// Query
$query=sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
mysql_real_escape_string($user),
mysql_real_escape_string($password));
?>Example #2mysql_real_escape_string() requires a connection example
This example demonstrates what happens if a MySQL connection is not present when calling this function.
<?php
// We have not connected to MySQL
$lastname="O'Reilly";
$_lastname=mysql_real_escape_string($lastname);
$query="SELECT * FROM actors WHERE last_name = '$_lastname'";
var_dump($_lastname);
var_dump($query);
?>The above example will outputsomething similar to:
Warning: mysql_real_escape_string(): No such file or directory in /this/test/script.php on line 5Warning: mysql_real_escape_string(): A link to the server could not be established in /this/test/script.php on line 5bool(false)string(41) "SELECT * FROM actors WHERE last_name = ''"
Example #3 An example SQL Injection Attack
<?php
// We didn't check $_POST['password'], it could be anything the user wanted! For example:
$_POST['username'] ='aidan';
$_POST['password'] ="' OR ''='";
// Query database to check if there are any matching users
$query="SELECT * FROM users WHERE user='{$_POST['username']}' AND password='{$_POST['password']}'";
mysql_query($query);
// This means the query sent to MySQL would be:
echo$query;
?>The query sent to MySQL:
SELECT * FROM users WHERE user='aidan' AND password='' OR ''=''
This would allow anyone to log in without a valid password.
Note:
A MySQL connection is required before usingmysql_real_escape_string() otherwise an error of level
E_WARNINGis generated, andfalseis returned. Iflink_identifierisn't defined, the last MySQL connection is used.
Note:
If this function is not used to escape data, the query is vulnerable toSQL Injection Attacks.
Note:mysql_real_escape_string() does not escape
%and_. These are wildcards in MySQL if combined withLIKE,GRANT, orREVOKE.
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.<?phpfunctionmysql_escape_mimic($inp) { if(is_array($inp)) returnarray_map(__METHOD__,$inp); if(!empty($inp) &&is_string($inp)) { returnstr_replace(array('\\',"\0","\n","\r","'",'"',"\x1a"), array('\\\\','\\0','\\n','\\r',"\\'",'\\"','\\Z'),$inp); } return$inp;}?>For further information:http://dev.mysql.com/doc/refman/5.5/en/mysql-real-escape-string.html(replace your MySQL version in the URL)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.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:"INSERT INTO X (A) VALUES(".$_POST["a"].")"You should use mysqli's prepare() function (http://php.net/manual/en/mysqli.prepare.php) to execute a statement that looks like this:"INSERT INTO X (A) VALUES(?)"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.