禁用“魔术引号”后,为什么PHP / Wordpress会继续自动转义我的POST数据?

时间:2012-01-21 00:49:24

标签: php wordpress escaping

这是一个简单的问题,有一个奇怪难以捉摸的答案。

get_magic_quotes_gpc()报告0.我再说一遍,魔术报价已经关闭。魔术引号似乎已在php.ini中禁用(不在运行时)。

然而,当在PHP中访问时,所有包含单引号(')的POST数据都会被转义。可能导致这种情况的原因是什么?

谢谢。


编辑: 对于好奇,这是我们的phpinfo的截图: http://img843.imageshack.us/img843/6959/screenshot20120120at552.png


编辑:在准备测试用例时,我发现了问题的一般原因。当我们的应用程序与WP Multisite安装集成时,我们正在引导Wordpress。当我禁用Wordpress引导时,自动转义被禁用。有谁知道Wordpress的自动转义码可能位于何处?

6 个答案:

答案 0 :(得分:38)

我想我找到了它。问题(错误):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的优秀答案。

答案 1 :(得分:14)

通过更深入的解释扩展@ 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 et代替$_POST(记住它是全球而不是超全球)你需要的地方。另请记住,虽然您的插件已在主题之前加载,但如果主题调用其中一个使用$_POST的插件函数,则应从$_REAL_POST读取以获取未转义的值。

答案 2 :(得分:0)

这里提供的最佳答案是复制自己使用,如:

$post = array_map('stripslashes_deep', $_POST);
然而,理论上有一个理论上的问题:既然你正在处理一个副本,你就不能坚持对超全球的任何改变(嘿,我不是说它'好的做法,好吗?)。

解决方案:存取方法

为了尝试以明确的方式解决这个混乱并且没有任何副作用,我制作了#34;存取方法"透明地应用stripslashes_deep()addslashes_deep()*来获取/设置对以下超全局数组的请求:

*我不得不从WordPress'一起抛出addslashes_deep()stripslashes_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); }

?>

答案 3 :(得分:0)

我只需处理这个问题,发现我认为是一个非常好的解决方法。它确保GPC永远不会被削减。我只是将它放在我的插件文件的顶部(我认为它也可以在主题的顶部工作):

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);
}

现在一切都很完美!

答案 4 :(得分:0)

Wordpress通过使用wordpress函数stripslashes_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_deep()。

答案 5 :(得分:-2)

或者,就像我做的那样。注释掉load.php的wp_magic_quotes()方法中的所有实现。

我没有使用魔法引号。这让我头疼得多,不仅仅是值得的。就个人而言,我更喜欢保持自己的输入卫生纪律。我只是不想开始形成糟糕的编程习惯。

但是,我确实理解WordPress强迫包含这样一个“功能”。也许开发社区最好有一个全局选项来禁用它。