【问题标题】:PHP replaces spaces with underscoresPHP用下划线替换空格
【发布时间】:2008-11-12 12:10:36
【问题描述】:

我有一个问题,PHP 将 POST 和 GET 变量中的所有空格替换为下划线。

例如,如果我有 URL:http://localhost/proxy.php?user name=Max 浏览器会将其转换为http://localhost/proxy.php?user%20name=Max

但是如果我把 $_GET 参数给出,关键不是user name而是user_name(注意下划线)!

有没有可能改变这种行为?

【问题讨论】:

标签: php


【解决方案1】:

来自PHP manual

传入变量名中的点

通常,PHP 不会更改 变量名 传递到脚本中。然而,它 应该注意的是点(句号, 句号)不是一个有效的字符 PHP 变量名。由于这个原因, 看看吧:

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

现在,什么 解析器看到的是一个名为的变量 $varname,后跟字符串 连接运算符,后跟 裸字符串(即不带引号的字符串 不匹配任何已知密钥或 保留字)'ext'。显然,这 没有达到预期的结果。

因此,重要的是 注意 PHP 会自动 替换传入变量中的任何点 带下划线的名称。

以及页面上的评论:

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

chr(32) ( ) (space)
chr(46) (.) (dot)
chr(91) ([) (open square bracket)
chr(128) - chr(159) (various)

PHP 不可逆地修改包含这些字符的字段名称,以保持与已弃用的 register_globals 功能的兼容性。

【讨论】:

  • 奇怪的是,如果我尝试将第二段作为引用而不是代码,编辑器会进入无限循环
  • 据我记得方括号不是简单地用下划线代替,而是允许将多个值放入一个数组中。
  • 我认为这意味着如果你只有一个,例如“hell[o”。如果您有匹配的对,那么您是正确的,它将创建一个数组。
  • 我不认同他们的论点。正确的做法是保持 $_GET 不变,只修改那些全局变量名。
【解决方案2】:

我认为获得所需参数的唯一可能性是使用 $_SERVER['QUERY_STRING'] 自行解析它们:

$a_pairs = explode('&', $_SERVER['QUERY_STRING']);
foreach($a_pairs AS $s_pair){
  $a_pair = explode('=', $s_pair);
  if(count($a_pair) == 1) $a_pair[1] = '';

  $a_pair[0] = urldecode($a_pair[0]);
  $a_pair[1] = urldecode($a_pair[1]);

  $GLOBALS['_GET'][$a_pair[0]] = $a_pair[1];
  $_GET[$a_pair[0]] = $a_pair[1];
}

【讨论】:

  • 今天注意到,诸如“foo[0]=bar”之类的“数组”参数不会按预期进行解释。
  • 正确,但您可能不希望这样,如果您期望的字段名称不是正确的 PHP 变量名称,并且会被 PHP 内置解析器破坏。
  • 对于 Rudi 的查询字符串解析器的更简洁(并且副作用更少)版本,我写了这个:$query=array_reduce(array_map(function($part){return array_map(function($kv){return urldecode($kv); },explode('=',$part,2));},explode('&amp;',$_SERVER['QUERY_STRING'])),function($query,$pair){$query[$pair[0]]=@$pair[1];return $query;},[]);(你可能想把它复制出来并正确格式化)跨度>
【解决方案3】:

在过去疯狂的 register_globals 查询字符串被 PHP 解包到全局变量中,但是变量标识符的格式受到限制,所以显然空格不能工作。这个限制仍然存在,老实说,我认为保持这种状态是个好主意。

如果您确实无法将 URL 中的空格更改为下划线,只需在处理请求时修改 $_GET 数组并将每个下划线替换为空格即可。

【讨论】:

    【解决方案4】:

    据我所知,我从未在 URL 参数名称中看到空格...

    我觉得,最好把参数名的所有空格都转换成“_”。

    【讨论】:

    • 我在将点转换为“”时遇到了同样的问题。我想使用点与具有别名表名的数据库表直接匹配,例如 table_name.column_name。当 php 将点转换为“”时,字符串变为不可用的“table_name_column_name”。你会怎么解决呢?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-12
    • 2020-02-03
    • 1970-01-01
    • 2010-11-03
    • 1970-01-01
    • 2013-11-08
    相关资源
    最近更新 更多