当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《让PHP停止替换'.'$_GET或$_POST数组中的字符?》经验,为你挑选了6个好方法。

如果我.通过$ _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.



1> Jeremy Ruten..:

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


这是*为什么*的一个很好的解释,但没有回答"有没有办法让它停止"的原始问题; 下面的其他答案确实提供了原始问题的答案.

2> crb..:

很久以来一直回答问题,但实际上有更好的答案(或解决方法).PHP允许您处理原始输入流,因此您可以执行以下操作:

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

这将为您提供查询字符串格式的$ _POST数组,它们应该是句点.

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


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


为了使用GET参数,使用`$ _SERVER ['QUERY_STRING']`替换`file_get_contents("php:// input")`.
这是一个良好的开端,但它有几个问题.它不处理数组值(例如foo.bar [] = blarg不会以数组结尾,它最终将作为一个名为foo.bar []的标量变量.它重新处理所有值时也会有很多开销,无论它们是否存在句点.

3> scipilot..:

在上面的评论中突出显示Johan的实际答案 - 我只是将我的整个帖子包装在顶级数组中,完全绕过问题而不需要繁重的处理.

在你做的形式

  
  
  

代替

 
 
  

并在邮政处理程序中,只需打开它:

$posdata = $_POST['data'];

对我而言,这是一个两线的变化,因为我的观点完全是模板化的.

仅供参考.我在字段名称中使用点来编辑分组数据的树.


确实非常优雅和实用的解决方案,具有保持表单数据很好地命名空间的附带好处.

4> Rok Kralj..:

这个功能的工作是我在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代替bin2hexbase64_decode代替的hex2bin.



5> Ja͢ck..:

发生这种情况是因为句点是变量名称中的无效字符,其原因在于PHP的实现非常深入,因此没有简单的修复(尚未).

在此期间,您可以通过以下方式解决此问题:

    通过php://inputPOST数据或$_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'));



6> El Yobo..:

这种方法是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;                                              
        }                                                                      
    }                                                                          
}                                                                              

推荐阅读
pan2502851807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有