如果我.
通过$ _GET PHP在其名称中传递PHP变量,则自动用_
字符替换它们.例如:
"; echo "x.y is ".$_GET['x.y']."."; echo "x_y is ".$_GET['x_y'].".
";
...输出以下内容:
url is /SpShipTool/php/testGetUrl.php?x.y=a.b x.y is . x_y is a.b.
......我的问题是这样的:有什么方法可以阻止它吗?不能为我的生活弄清楚我做了什么值得这样做
我运行的PHP版本是5.2.4-2ubuntu5.3.
这是PHP.net对其原因的解释:
输入变量名称中的点
通常,PHP在传递到脚本时不会更改变量的名称.但是,应该注意,点(句点,句号)不是PHP变量名中的有效字符.出于这个原因,看看它:
现在,解析器看到的是一个名为$ varname的变量,后跟字符串连接运算符,后跟barestring(即不带引号的字符串,它与任何已知的密钥或保留字不匹配)'ext'.显然,这没有预期的结果.
因此,请务必注意PHP会自动使用下划线替换传入变量名中的任何点.
那是来自http://ca.php.net/variables.external.
此外,根据此评论,这些其他字符将转换为下划线:
PHP转换为_(下划线)的字段名称字符的完整列表如下(不仅仅是点):
chr(32)()(空格)
chr(46)(.)(点)
chr(91)([)(空方括号)
chr(128) - chr(159)(各种)
因此看起来你已经坚持使用它,所以你必须使用dawnerd的建议将下划线转换回脚本中的点(我只是使用str_replace.)
很久以来一直回答问题,但实际上有更好的答案(或解决方法).PHP允许您处理原始输入流,因此您可以执行以下操作:
$query_string = file_get_contents('php://input');
这将为您提供查询字符串格式的$ _POST数组,它们应该是句点.
然后,如果需要,您可以解析它(根据POSTer的评论)
对于包含'.'的OpenID参数非常有用.和'_',每个都有一定的意义!
在上面的评论中突出显示Johan的实际答案 - 我只是将我的整个帖子包装在顶级数组中,完全绕过问题而不需要繁重的处理.
在你做的形式
代替
并在邮政处理程序中,只需打开它:
$posdata = $_POST['data'];
对我而言,这是一个两线的变化,因为我的观点完全是模板化的.
仅供参考.我在字段名称中使用点来编辑分组数据的树.
这个功能的工作是我在2013年暑假期间提出的一个天才黑客.我有一天会写一篇关于它的博客文章.
例如,此修复程序通用并且具有深度阵列支持a.a[x][b.a]=10
.它parse_str()
在幕后使用一些预处理.
function fix($source) { $source = preg_replace_callback( '/(^|(?<=&))[^=[&]+/', function($key) { return bin2hex(urldecode($key[0])); }, $source ); parse_str($source, $post); $result = array(); foreach ($post as $key => $val) { $result[hex2bin($key)] = $val; } return $result; }
然后你可以像这样调用这个函数,具体取决于来源:
$_POST = fix(file_get_contents('php://input')); $_GET = fix($_SERVER['QUERY_STRING']); $_COOKIE = fix($_SERVER['HTTP_COOKIE']);
对于低于5.4 PHP:使用base64_encode
代替bin2hex
和base64_decode
代替的hex2bin
.
发生这种情况是因为句点是变量名称中的无效字符,其原因在于PHP的实现非常深入,因此没有简单的修复(尚未).
在此期间,您可以通过以下方式解决此问题:
通过php://input
POST数据或$_SERVER['QUERY_STRING']
GET数据访问原始查询数据
使用转换功能.
下面的转换函数(PHP> = 5.4)将每个键值对的名称编码为十六进制表示,然后执行常规parse_str()
; 完成后,它会将十六进制名称恢复为原始形式:
function parse_qs($data) { $data = preg_replace_callback('/(?:^|(?<=&))[^=[]+/', function($match) { return bin2hex(urldecode($match[0])); }, $data); parse_str($data, $values); return array_combine(array_map('hex2bin', array_keys($values)), $values); } // work with the raw query string $data = parse_qs($_SERVER['QUERY_STRING']);
要么:
// handle posted data (this only works with application/x-www-form-urlencoded) $data = parse_qs(file_get_contents('php://input'));
这种方法是Rok Kralj的改进版本,但需要进行一些调整,以提高效率(避免不必要的回调,对未受影响的键进行编码和解码)并正确处理数组键.
我们提供了有测试的要点,欢迎任何反馈或建议.
public function fix(&$target, $source, $keep = false) { if (!$source) { return; } $keys = array(); $source = preg_replace_callback( '/ # Match at start of string or & (?:^|(?<=&)) # Exclude cases where the period is in brackets, e.g. foo[bar.blarg] [^=&\[]* # Affected cases: periods and spaces (?:\.|%20) # Keep matching until assignment, next variable, end of string or # start of an array [^=&\[]* /x', function ($key) use (&$keys) { $keys[] = $key = base64_encode(urldecode($key[0])); return urlencode($key); }, $source ); if (!$keep) { $target = array(); } parse_str($source, $data); foreach ($data as $key => $val) { // Only unprocess encoded keys if (!in_array($key, $keys)) { $target[$key] = $val; continue; } $key = base64_decode($key); $target[$key] = $val; if ($keep) { // Keep a copy in the underscore key version $key = preg_replace('/(\.| )/', '_', $key); $target[$key] = $val; } } }