Fix to Replicate “Magic Quotes” and “Register Globals” in PHP 5.4+

It pains me to write this post in 2013, but after doing some client work recently, I’ve found that these issues still actually exist in the wild, so these “fixes” may potentially help people.

A little history… Back in the day, PHP had a feature called “Magic Quotes” (magic_quotes_gpc). When it was on, all ‘ (single-quote), ” (double quote), \ (backslash) and NULL characters in the $_POST, $_GET and $_COOKIE arrays would be escaped with a backslash automatically. Like many things in PHP, it was a bad idea. But it was often turned on by default, so people became dependent on it. Specifically, they would do things like this:

mysql_query("INSERT INTO records SET name = '{$_POST['name']}'");

That statement has a number of things wrong with it (using a deprecated MySQL API is among them), but the biggest issue is that it assumes $_POST['name'] has been properly escaped to prevent SQL injection. That assumption is (dangerously) based on PHP’s “Magic Quotes” being enabled. Unfortunately, there’s still lots of terrible legacy code like this out there. This type of thing fell out of practice 8+ years ago, but you’d be surprised how long sites will stick around, untouched.

“Magic Quotes” was depreciated in PHP 5.3.0 (2009) and was dropped completely in PHP 5.4.0 (2012). I recently had to move a client’s (very old) PHP site to a new server running PHP 5.4. The code depended on “Magic Quotes” being enabled. Since that was now impossible, lots of things broke. Refactoring the code was, unfortunately, not an option. Instead, I had to implement the quick hack below. As long as this is placed in a globally included file before any processing is done (e.g. – the database connection file), it’ll replicate the magic_quotes_gpc functionality and add slashes to the $_POST and $_GET arrays (you could also do this with $_COOKIE, if you’d like).

// This replicates magic_quotes_gpc in PHP 5.4+
foreach($_POST as $key => $val){
  $_POST[$key] = addslashes($val);
foreach($_GET as $key => $val){
  $_GET[$key] = addslashes($val);

Believe me, I’m not proud of this solution — or even the fact that I’m dealing with sites this old. But if you run into the same problem, you now have a possible fix.

While I’m at it, if you need to replicate register_globals (I hope you don’t), here’s a snippet for doing that. This will take the values in your $_POST and $_GET arrays and make them available as independent global variables (e.g. – $_POST['name'] will be accessible as $name).

// This replicates register_globals in PHP 5.4+
foreach (array_merge($_GET, $_POST) as $key => $val) {
  global $$key;
  $$key = addslashes($val);

Disclaimer: I’d strongly suggest refactoring your code over using any of these hacks. Only use them if you must.

  • James Byrne

    I got a call from a client yesterday with this same issue and after reading your article was able to produce a simple fix. Thanks for article.

    • James, great! Glad the article was useful for you.

  • guest

    Yes, Bluehost just forcibly “upgraded” my site to php 5.4 and it broke all of my code. I was using magic_quotes_gpc = ON in the php.ini and now I’ve got to go re-do everything in emergency mode. Thank you, NOT, PHP and Bluehost.

  • Magicquotes are magical

    Our inhouse production website (in theory not exposed to the outside world) utilizes this “bad idea of magicquotes” and for someone like myself it was invaluable as I’m not a programmer. Not a fan of it being deprecated but I understand given the vulnerabilities in the public. I don’t understand the fix presented here and am having to addslashes and stripslashes to hundreds of lines of code. By the way, Justin, you are the most attractive web geek I’ve ever seen on the internet.

  • Andrew

    I spent almost an entire day trying to migrate an old PHP site to PHP 5. Your code is a real life saver. Thanks a million.
    Keep up the Good Work.

  • Steven

    If the application sends POST data with square brackets in the name, you’ll need to implement a solution that traverses the array, as PHP will interpret names like dataGroup[subElement] into a proper associative array inside $_POST.

    • Steven, good point. The solution above assumes that $_POST is always going to be flat associative array. If it’s going to have nested arrays, you’ll need to modify this to recursively check for and handle that.

  • Will

    Hello Justin I have oscommerce.
    Where do I have to put those two files in.

  • rembem

    Thank you so much for posting this. I had an 11 year old but immensely popular very large website suddenly on a new server and nothing working anymore because of the removed magic_quotes_gpc in the newer php version. Refactoring the old code: not an option. This really saved my day, so glad to have found your solution. Proud of this hack? No. Glad? YES!