让 PHP 停止替换 $_GET 或 $_POST 数组中的 '.' 字符?

2022-08-30 08:02:49

如果我通过 $_GET 将 PHP 变量的名称与 它们一起传递,PHP 会自动用字符替换它们。例如:._

<?php
echo "url is ".$_SERVER['REQUEST_URI']."<p>";
echo "x.y is ".$_GET['x.y'].".<p>";
echo "x_y is ".$_GET['x_y'].".<p>";

...输出以下内容:

url is /SpShipTool/php/testGetUrl.php?x.y=a.b
x.y is .
x_y is a.b.

...我的问题是:有什么办法可以让它停止吗?我无法为我的生活弄清楚我做了什么才配得上这个

我运行的PHP版本是5.2.4-2ubuntu5.3。


答案 1

以下是PHP.net对它为什么这样做的解释:

传入变量名称中的点

通常,PHP 在将变量传递到脚本中时不会更改变量的名称。但是,应该注意的是,点(句点,句号)不是PHP变量名称中的有效字符。出于这个原因,看看它:

<?php
$varname.ext;  /* invalid variable name */
?>

现在,解析器看到的是一个名为 $varname 的变量,后跟字符串串联运算符,后跟裸字符串(即与任何已知键或保留字都不匹配的未加引号字符串)'ext'。显然,这没有预期的结果。

因此,请务必注意,PHP 会自动将传入变量名称中的任何点替换为下划线。

这是从 http://ca.php.net/variables.external 开始的。

此外,根据此注释,这些其他字符将转换为下划线:

PHP 转换为 _( 下划线)的字段名称字符的完整列表如下(不仅仅是点):

  • chr(32) ( ) (空格)
  • chr(46) (.)(点)
  • chr(91) ([) (左方括号)
  • chr(128) - chr(159) (各种)

所以看起来你被困住了,所以你必须使用dawerd的建议将下划线转换回脚本中的点(不过我只使用str_replace)。


答案 2

很久以来,问题已经回答过了,但实际上有更好的答案(或变通方法)。PHP允许您在原始输入流中,因此您可以执行如下操作:

$query_string = file_get_contents('php://input');

这将为您提供查询字符串格式的 $_POST 数组,句点应如此。

然后,您可以根据需要解析它(根据POSTer的评论))

<?php
// Function to fix up PHP's messing up input containing dots, etc.
// `$source` can be either 'POST' or 'GET'
function getRealInput($source) {
    $pairs = explode("&", $source == 'POST' ? file_get_contents("php://input") : $_SERVER['QUERY_STRING']);
    $vars = array();
    foreach ($pairs as $pair) {
        $nv = explode("=", $pair);
        $name = urldecode($nv[0]);
        $value = urldecode($nv[1]);
        $vars[$name] = $value;
    }
    return $vars;
}

// Wrapper functions specifically for GET and POST:
function getRealGET() { return getRealInput('GET'); }
function getRealPOST() { return getRealInput('POST'); }
?>

对于 OpenID 参数非常有用,这些参数同时包含 '.' 和 '_',每个参数都有一定的含义!


推荐