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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2496455/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 06:42:19  来源:igfitidea点击:

Why are $_POST variables getting escaped in PHP?

phpajaxpostescaping

提问by Nathan Osman

When my PHP script receives data from an AJAX POST request, the $_POSTvariables are escaped. The really strange thing is that this only happens on my production server (running PHP 5.2.12 on Linux) and not on my local server (running PHP 5.3.1 on Windows).

当我的 PHP 脚本从 AJAX POST 请求接收数据时,$_POST变量被转义。真正奇怪的是,这只发生在我的生产服务器(在 Linux 上运行 PHP 5.2.12)而不是在我的本地服务器上(在 Windows 上运行 PHP 5.3.1)。

Here is the AJAX code:

这是 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);

Is there any reason this is happening? And how should I fix this so that it works on both servers?

发生这种情况有什么原因吗?我应该如何解决这个问题,以便它在两台服务器上都能正常工作?

Edit: I have the following settings for magic_quotes:

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

                     Local   Master

magic_quotes_gpc     On      On
magic_quotes_runtime Off     Off
magic_quotes_sybase  Off     Off

回答by Pekka

You probably have magic quotes enabled on the Linux server: magic_quotes

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

When magic_quotes are on, all ' (single-quote), " (double quote), \ (backslash) and NUL's are escaped with a backslash automatically.

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

They're a good thing to disable, as they are going to be removed from PHP 6 onwards anyway. You should also be able to disable them inside your script: set-magic-quotes-runtimeYou can't deactivate the part of magic_quotes responsible for escaping POST data during runtime. If you can, disable it in php.ini. If you can't do that, do a check whether the magic_quotes are enabled, and do a stripslashes() on any content you fetch from POST:

禁用它们是一件好事,因为无论如何它们都将从 PHP 6 开始删除。 您还应该能够在脚本中禁用它们:set-magic-quotes-runtime您不能停用负责在运行时转义 POST 数据的 magic_quotes 部分。如果可以,请在 php.ini 中禁用它。如果您不能这样做,请检查是否启用了 magic_quotes,并对您从 POST 获取的任何内容执行 stripslashes() :

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

回答by Syntax Error

I don't think this applies in your case, but I was just having a similar problem. I was loading a WordPress install along with a site, so I could show recent posts on all pages. It turns out WordPress escapes all $_POST vars, no matter what magic_quotes are set to.

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

I mention it because it was frustrating to figure out, and googling for an answer brought me here.

我提到它是因为弄清楚这件事令人沮丧,谷歌搜索将我带到了这里。

Here's how I fixed it in my case:

这是我在我的情况下修复它的方法:

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

回答by Matchu

This is a PHP "feature" known as Magic Quotes, which has now been deprecated in PHP 5.3 and removed in PHP 5.4.

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

It is easy to disable the silly nuisance in php.ini.

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

回答by BojanG

You likely have magic quotes turned on in your production environment. Inspect phpinfo()output.

您可能在生产环境中打开了魔术引号。检查phpinfo()输出。

You can run all of your inputs through something like this to strip the quotes:

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

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

回答by Toskan

So I did talk to a WordPress developer (#40476. $_POST values ' and \ for sure are getting escaped with a slash) and he said:

因此,我确实与 WordPress 开发人员(#40476. $_POST values ' 和 \ 肯定会被斜杠转义)交谈,他说:

Back in the day, many many moons ago, WordPress blindly followed PHP in accepting that all of the superglobal values should be slashed. PHP later did a reversal on the idea to something more sane which you see today, but the damage was done.

WordPress as an application had existed for long enough, and there were enough existing plugins and themes relying upon WordPress creating a sane single environment that WordPress also changing would cause irreparable damage to those sites - introduce security vulnerabilities, mangle content, and a bunch of other fun things.

https://core.trac.wordpress.org/ticket/18322is our ticket for tracking this and getting to something more sane - in the shortterm (and longer term) we'd request that if you're accessing $_POST variables you do it as such: $myvar = wp_unslash( $_POST['variable'] ); so that one day, we'll be able to have $_POST as an unslashed array.

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

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

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

Concerning the answer given here:

关于这里给出的答案:

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

Please don't do that. You're just opening yourself to security issues, and unexpected things happening to your content where WordPress does expect the values to be slashed. Instead, simply use wp_unslash(), and if you really need a copy of $_POST to operate on yourself, do it as such: $my_POST = wp_unslash( $_POST );.

请不要那样做。您只是让自己面临安全问题,并且您的内容会发生意外的事情,而 WordPress 确实希望这些值会被削减。相反,简单地使用wp_unslash(),如果你真的需要$ _ POST的副本来对自己进行操作,做到这样:$my_POST = wp_unslash( $_POST );

I should also add - I expect you're doing this because you're trying to use an API endpoint for something, I'd highly suggest switching to using the REST API introduced with WordPress 4.7 instead, as it allows us to offer much more consistent experience to developers.

我还应该补充 - 我希望你这样做是因为你正在尝试使用 API 端点来做某事,我强烈建议改用 WordPress 4.7 引入的 REST API,因为它允许我们提供更多为开发人员提供一致的体验。

回答by alex

Maybe your Linux server's php.ini has magic quotes enabled.

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

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

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

This is bad of course, as the functionality is deprecated and will be removed in the forthcoming PHP 6.

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

You can disable it in php.ini like so

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

magic_quotes_gpc = Off

You can test and disable it at runtime if you can not access your php.ini

如果您无法访问您的 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);
}
?>

From the PHP Manual

来自PHP 手册

回答by Andrii

Elegant solution, based on the all answers

优雅的解决方案,基于所有答案

if ( get_magic_quotes_gpc() ) {
    array_walk_recursive( $_POST, function ( &$element ) {
        $element = stripslashes( $element );
    } );
}