这是一个简单的问题,却有一个奇怪而难以捉摸的答案。
get_magic_quotes_gpc()
报告0。我重复一遍,魔术引号是关闭的。魔术引号似乎在php.ini
中被禁用了(不是在运行时)。
尽管如此,在PHP中访问时,包括单引号(')在内的所有POST数据都会被转义。是什么原因造成的?
在准备测试用例时,我发现了问题的一般根源。我们正在引导WordPress,因为我们的应用程序与WordPress多站点安装集成。当我禁用WordPress引导时,自动转义被禁用。WordPress的自动转义码在哪里?
我想我找到了。问题(bug):http://core.trac.wordpress.org/ticket/18322
解决方案:http://codex.wordpress.org/Function_Reference/stripslashes_deep
$_GET = array_map('stripslashes_deep', $_GET);
$_POST = array_map('stripslashes_deep', $_POST);
$_COOKIE = array_map('stripslashes_deep', $_COOKIE);
$_SERVER = array_map('stripslashes_deep', $_SERVER);
$_REQUEST = array_map('stripslashes_deep', $_REQUEST);
注意:正如@Alexandar O'Mara所建议的,您可能需要重新考虑像这样覆盖超全局。例如,如果它适合您的情况,您可以使用$post = array_map('stripslashes_deep', $_POST);
等替代方案"本地剥离"
另请参阅@quickshiftin的精彩回答。
用更深入的解释扩展@rinogo的答案,并提供另一种解决方法。
在wp-settings.php中,有一个对wp_magic_quotes
的无条件调用
// Add magic quotes and set up $_REQUEST ( $_GET + $_POST )
wp_magic_quotes();
WordPress无论是什么都能转义引号
function wp_magic_quotes() {
// If already slashed, strip.
// Escape with wpdb.
// Force REQUEST to be GET + POST.
}
有趣的是,这个调用是在加载插件之后进行的,在加载主题之前。Sooo,在你的插件的顶部
// A hack to cope with un-configurable call to wp_magic_quotes
// E.G. Make the original $_POST available through a global $_REAL_POST
$_REAL_GET = $_GET;
$_REAL_POST = $_POST;
$_REAL_COOKIE = $_COOKIE;
$_REAL_REQUEST = $_REQUEST;
然后,您可以在需要的地方自由使用$_REAL_POST
等来代替$_POST
(记住它是全局,而不是超全局
我刚刚处理了这个问题,发现了一个我认为非常好的解决方法。它可以确保GPCs从不被削减。我只是把它放在我的插件文件的顶部(我认为它也可以放在主题的顶部):
add_action( 'init', 'unslash_gpc' );
function unslash_gpc() {
$_GET = array_map('stripslashes_deep', $_GET);
$_POST = array_map('stripslashes_deep', $_POST);
$_COOKIE = array_map('stripslashes_deep', $_COOKIE);
$_SERVER = array_map('stripslashes_deep', $_SERVER);
$_REQUEST = array_map('stripslashes_deep', $_REQUEST);
}
现在一切都很完美!
这里提供的最佳答案是复制以供自己使用,如:
$post = array_map('stripslashes_deep', $_POST);
然而,这有一个理论上的问题:由于你正在处理一个副本,你不能坚持对超全局的任何更改(嘿,我并不是说这是一个好的做法,好吗?)。
解决方案:访问器方法
为了在没有任何副作用的情况下以明确的方式解决这个问题,我制作了"访问器方法",它透明地应用stripslashes_deep()
或addslashes_deep()*
来获取/设置对以下超全局数组的请求:
*我不得不把WordPress的stripslashes_deep()
中的addslashes_deep()
放在一起
$_GET
$_POST
$_COOKIE
$_SERVER
$_REQUEST
你可以像这样使用它们:
echo _get('username'); // echo stripslashes_deep($_GET['username']);
_cookie('name', 'value'); // $_COOKIE['name'] = addslashes_deep('value');
这是代码(我称之为gpcsr.php
):
<?php
// cat stripslashes_deep() | sed 's/stripslashes/addslashes/g'
function addslashes_deep( $value ) {
if ( is_array($value) ) {
$value = array_map('addslashes_deep', $value);
} elseif ( is_object($value) ) {
$vars = get_object_vars( $value );
foreach ($vars as $key=>$data) {
$value->{$key} = addslashes_deep( $data );
}
} elseif ( is_string( $value ) ) {
$value = addslashes($value);
}
return $value;
}
function _generic_slashes_wrap(&$arr, $key, $value = null) {
if (func_num_args() === 2) return stripslashes_deep($arr[$key]);
else $arr[$key] = addslashes_deep($value);
}
function _get ($key, $value = null) { if (func_num_args() === 1) return _generic_slashes_wrap($_GET, $key); else _generic_slashes_wrap($_GET, $key, $value); }
function _post ($key, $value = null) { if (func_num_args() === 1) return _generic_slashes_wrap($_POST, $key); else _generic_slashes_wrap($_POST, $key, $value); }
function _cookie ($key, $value = null) { if (func_num_args() === 1) return _generic_slashes_wrap($_COOKIE, $key); else _generic_slashes_wrap($_COOKIE, $key, $value); }
function _server ($key, $value = null) { if (func_num_args() === 1) return _generic_slashes_wrap($_SERVER, $key); else _generic_slashes_wrap($_SERVER, $key, $value); }
function _request ($key, $value = null) { if (func_num_args() === 1) return _generic_slashes_wrap($_REQUEST, $key); else _generic_slashes_wrap($_REQUEST, $key, $value); }
?>
WordPress通过使用WordPress函数stripslase_deep提供了一个解决方案。因此,@rinogo的回答中提到的片段将变成:
$_GET = stripslashes_deep($_GET);
$_POST = stripslashes_deep($_POST);
$_COOKIE = stripslashes_deep($_COOKIE);
$_REQUEST = stripslashes_deep($_REQUEST);
另外需要注意的是,WordPress没有说明任何关于$_SERVER
全局变量的内容,所以我认为它没有受到影响。
无论GET_magic_quotes_gpc()返回什么,WordPress都会向$_POST/$_GET/$_REQUEST/$_COOKIE添加斜杠。因此,在WordPress的上下文中,在使用这些变量时,应该始终使用stripslashes()或stipslashes_dep()。
或者,就像我做的那样。注释掉load.php的wp_magic_quotes()方法中的所有实现。
我没有魔法名言的用处。这让我头疼得厉害。就我个人而言,我更喜欢保持我自己的投入卫生纪律。我只是不想开始养成坏的编程习惯。
但是,我确实理解WordPress强迫包含这样一个"功能"。也许开发社区最好有一个全局选项来禁用它。