WWW FAQs: Why does PHP insert \ in front of every " in my form data?


2006-09-01: PHP programmers are often puzzled when a \ character shows up in front of every ' or " entered in a form submission by a user. These slashes come from PHP's useless and dangerous "magic quotes" feature.

"Magic quotes" is a mechanism that automatically inserts a \ in front of every ", ' and certain other characters as well. This is done because PHP assumes you are going to store this information in a SQL database, where quotation marks have special meanings and could be used to hack your script.

This is a nice idea, but completely useless in practice because it doesn't protect you adequately. Every database package is slightly different, and there are exploitable means to construct "SQL injection" attacks which get past the naive checks that addslashes() performs. So this feature only leads to a false sense of security and potential website hacks.

Unless the script is on your own web server and you have control over php.ini, you can't be sure the feature is turned on, so you have to write code to deal with it being turned off anyway. Or better yet, code to undo its effects completely, which I'll show you. And then, of course, you need to escape strings correctly for your database software.

In short: "magic quotes" makes life frustrating and creates a dangerous illusion of safety. It should be removed from a future release of PHP. In the meantime, here's how to cope with it.

How To Undo Magic Quotes

To undo the unwanted effects of "magic quotes," use the following code - but make very sure you read on to find out how to correctly "escape" special characters and avoid SQL injection attacks on your website.

This code will undo the effects of magic quotes if they are in effect. Note that the set_magic_quotes_runtime() PHP function that some people recommend does not do this.


function stripslashes_nested($v)
{
  if (is_array($v)) {
    return array_map('stripslashes_nested', $v);
  } else {
    return stripslashes($v);
  }
}

if (get_magic_quotes_gpc()) {
  $_GET = stripslashes_nested($_GET);
  $_POST = stripslashes_nested($_POST);
  $_COOKIES = stripslashes_nested($_COOKIES);
}

How To Correctly Escape Your SQL Queries

This is extremely important! If you are working with a database, you do need a way to correctly quote special characters when writing SQL statements. We can't just throw away the inadequate protection of magic quotes and forget about the problem.

The correct solution depends on which database software you are using. If you are using MySQL, you should use the mysql_real_escape_string() function, like this:


#The user says this is his name
$name = $_POST['name'];

#But do we trust him? NO!
$name = mysql_real_escape_string($name);

#NOW $name is safe to pass in a MySQL query.

Even this solution can be outsmarted if you are changing the character set in MySQL "on the fly." The mysql_real_escape_string() function doesn't know, so it becomes possible to trick it once again. Those who are not changing character sets on the fly don't need to worry about this. For more information, see Ilia Alshanetsky's excellent article mysql_real_escape_string() versus Prepared Statements.

Those who administer their own web servers can disable the magic quotes feature permanently by adding this line to php.ini:


; Magic quotes is BAD NEWS, turn it off!
magic_quotes_gpc = Off

Legal Note: yes, you may use sample HTML, Javascript, PHP and other code presented above in your own projects. You may not reproduce large portions of the text of the article without our express permission.

Got a LiveJournal account? Keep up with the latest articles in this FAQ by adding our syndicated feed to your friends list!