为什么 $_POST 变量在 PHP 中会被转义?

问题描述 投票:0回答:6

当我的 PHP 脚本从 AJAX POST 请求接收数据时,

$_POST
变量会被转义。真正奇怪的是,这只发生在我的生产服务器(在 Linux 上运行 PHP 5.2.12)上,而不发生在我的本地服务器(在 Windows 上运行 PHP 5.3.1)上。

这是 AJAX 代码:

var pageRequest = false;
if(window.XMLHttpRequest)     pageRequest = new XMLHttpRequest();
else if(window.ActiveXObject) pageRequest = new ActiveXObject("Microsoft.XMLHTTP");

pageRequest.onreadystatechange = function() { }

var q_str = 'data=' + " ' ";

pageRequest.open('POST','unnamed_page.php',true);

pageRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
pageRequest.setRequestHeader("Content-length", q_str.length);
pageRequest.setRequestHeader("Connection", "close");

pageRequest.send(q_str);

发生这种情况有什么原因吗?我应该如何解决这个问题,以便它可以在两台服务器上运行?

编辑:我对 magic_quotes 有以下设置:

                     Local   Master

magic_quotes_gpc     On      On
magic_quotes_runtime Off     Off
magic_quotes_sybase  Off     Off
php ajax post escaping
6个回答
71
投票

您可能在 Linux 服务器上启用了魔术引号:magic_quotes

当 magic_quotes 打开时,所有 '(单引号)、"(双引号)、\(反斜杠)和 NUL 都会自动用反斜杠转义。

禁用它们是一件好事,因为无论如何它们都会从 PHP 5.4 开始被删除。 您无法停用 magic_quotes 中负责在运行时转义 POST 数据的部分。如果可以的话,请在 php.ini 中禁用它。如果你不能这样做,请检查 magic_quotes 是否启用,并对从 POST 获取的任何内容执行 stripslashes() :

if (get_magic_quotes_gpc())  
 $my_post_var = stripslashes($_POST["my_post_var"]);

31
投票

我认为这不适用于您的情况,但我也遇到了类似的问题。我正在加载 WordPress 安装和网站,因此我可以在所有页面上显示最近的帖子。事实证明,无论 magic_quotes 设置为多少,WordPress 都会转义所有 $_POST 变量。

我提到它是因为弄清楚这一点令人沮丧,并且通过谷歌搜索答案将我带到了这里。

这是我在我的案例中修复它的方法:

$temp_POST = $_POST;
require '../www/wp_dir/wp-load.php'; // Loading WordPress
$_POST = $temp_POST;

9
投票

这是一个名为 Magic Quotes 的 PHP“功能”,现已在 PHP 5.3 中弃用并在 PHP 5.4 中删除。

很容易禁用 php.ini 中的愚蠢麻烦。


5
投票

所以我确实和一位 WordPress 开发人员交谈过(#40476。$_POST 值 ' 和 \ 肯定是用斜杠转义的),他说:

很久以前,WordPress 盲目地跟随 PHP 接受所有超全局值都应该被削减。 PHP 后来将这个想法逆转为你今天看到的更理智的东西,但损害已经造成了。

WordPress 作为一个应用程序已经存在了足够长的时间,并且有足够多的现有插件和主题依赖于 WordPress 创建一个健全的单一环境,而 WordPress 的改变也会对这些网站造成不可挽回的损害 - 引入安全漏洞、破坏内容和一堆其他有趣的事情。

https://core.trac.wordpress.org/ticket/18322 是我们跟踪此问题并获得更理智的东西的门票 - 在短期(和长期),如果您正在访问 $ _POST 变量,您可以这样做: $myvar = wp_unslash( $_POST['variable'] );这样有一天,我们将能够将 $_POST 作为一个未斜线的数组。

关于这里给出的答案:

$temp_POST = $_POST;
require '../www/wp_dir/wp-load.php';
$_POST = $temp_POST;

请不要这样做。你只是让自己面临安全问题,以及你的内容发生意外的事情,而 WordPress 确实希望这些值被削减。 相反,只需使用

wp_unslash()
,如果您确实需要 $_POST 的副本来对自己进行操作,请按如下方式操作:
$my_POST = wp_unslash( $_POST );

我还应该添加 - 我希望您这样做是因为您正在尝试使用 API 端点来执行某些操作,我强烈建议改用 WordPress 4.7 引入的 REST API,因为它允许我们提供很多功能为开发者提供更一致的体验。


4
投票

您可能在生产环境中打开了魔术引号。检查

phpinfo()
输出。

您可以通过类似这样的方式运行所有输入以去除引号:

        /* strip slashes from the string if magic quotes are on */
    static function strip_magic_slashes($str)
    {
            return get_magic_quotes_gpc() ? stripslashes($str) : $str;
    }

2
投票

也许您的 Linux 服务器的 php.ini 启用了魔术引号。

http://php.net/manual/en/security.magicquotes.php

这当然很糟糕,因为该功能已被弃用,并将在即将发布的 PHP 6 中删除。

您可以像这样在 php.ini 中禁用它

magic_quotes_gpc = Off

如果无法访问 php.ini,可以在运行时测试并禁用它

<?php
if (get_magic_quotes_gpc()) {
    $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
    while (list($key, $val) = each($process)) {
        foreach ($val as $k => $v) {
            unset($process[$key][$k]);
            if (is_array($v)) {
                $process[$key][stripslashes($k)] = $v;
                $process[] = &$process[$key][stripslashes($k)];
            } else {
                $process[$key][stripslashes($k)] = stripslashes($v);
            }
        }
    }
    unset($process);
}
?>

来自 PHP 手册

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.