It's a simple question with a strangely elusive answer.
get_magic_quotes_gpc()
reports 0. I repeat, magic quotes are off. Magic quotes appear to have been disabled in php.ini
(not at runtime).
Nevertheless, all POST data including single quotes (') is escaped when accessed in PHP. What could be causing this?
Thank you.
Edit: For the curious, this is a screenshot of our phpinfo: http://img843.imageshack.us/img843/6959/screenshot20120120at552.png
Edit: While preparing a test case, I discovered the general origin of the problem. We're bootstrapping Wordpress as our app integrates with a WP Multisite installation. When I disable the Wordpress bootstrapping, the auto-escaping is disabled. Does anyone know where Wordpress' auto-escape code may be located?
I just had to deal with this issue and found what I think is a pretty nice workaround. It ensures that the GPCs are never slashed. I just put this at the top of my plugin file (it would work at the top of a theme too, I think):
And now everything is perfect!
I think I found it. Problem (bug): http://core.trac.wordpress.org/ticket/18322
Solution: http://codex.wordpress.org/Function_Reference/stripslashes_deep
Note: As suggested by @Alexandar O'Mara, you might want to reconsider overwriting the superglobals like this. If it's appropriate for your situation, for example, you might just "strip locally" using an alternative like
$post = array_map('stripslashes_deep', $_POST);
Also see @quickshiftin's excellent answer.
Expanding on @rinogo's answer with a deeper explanation, and offering another workaround.
In wp-settings.php there's an unconditional call to
wp_magic_quotes
Wordpress escapes quotes no matter what
What's interesting though is this call is made after plugins have been loaded, before the theme is loaded. Sooo, at the top of your plugin
Then you can freely use
$_REAL_POST
et al in place of$_POST
(remembering it's a global not a superglobal) where you need to. Also remember that while your plugin has loaded before the theme, if the theme calls down into one of the plugin functions which uses$_POST
, it should read from$_REAL_POST
to get the unescaped values.The best answer provided here is to copy for own use like:
There's a theoretical problem with this however: since you're working with a duplicate, you can't persist any changes to the superglobals (hey, I'm not saying it's a good practice, alright?).
Solution: accessor methods
In an attempt to solve this mess in a definite manner and without any side effects, I made "accessor methods" which transparently apply
stripslashes_deep()
oraddslashes_deep()*
to get/set requests to the following superglobal arrays:* I had to throw
addslashes_deep()
together from WordPress'stripslashes_deep()
.$_GET
$_POST
$_COOKIE
$_SERVER
$_REQUEST
You can use them like:
Here's the code (I call it
gpcsr.php
):Or, just do like I did. Comment out all of the implementation in load.php's wp_magic_quotes() method.
I have no use for magic quotes. This was causing me many more headaches than it was worth. Personally, I prefer to maintain my own discipline of input sanitation. I just don't want to start forming bad programming habits.
But, I do understand WordPress' compulsion to include such a "feature". Perhaps the development community would be best served with a global option to disable it.
Wordpress provides a solution for this by using the wordpress function stripslashes_deep. So, the snippets mentioned in @rinogo's answer would become :
Also a note, wordpress doesn't say anything about the
$_SERVER
global variable, so I would assume it's not affected.