dounieliang4712 2014-11-15 14:46
浏览 26
已采纳

PHP5.4“parse_str”意外行为

I am using Zend Framework 2's AbstractRestfulController to implement a CRUD API in our project. Using the PUT HTTP method invokes the logic for updating an existing entity.

When receiving a PUT request, the AbstractRestfulController transforms the request body to an array using PHP's parse_str function, but this function does not do what it is supposed to do.

Because it gave me odd results, I tried parse_str with the sample data provided in the PHP docs:

// sample data from the PHP docs
$content = "first=value&arr[]=foo+bar&arr[]=baz";

// put the parsed variables into $parsedParams
parse_str($content, $parsedParams);

var_dumping $parsedParams gives me the following

array(5) { 
    ["first"]=> string(1) "v" 
    ["lue"]=> string(0) "" 
    ["rr"]=> array(2) { 
        [0]=> string(5) "foo b" 
        [1]=> string(1) "b" 
    } 
    ["r"]=> string(0) "" 
    ["z"]=> string(0) "" 
} 

Apparently the character "a" confuses parse_str, but I have absolutely no idea what's causing this odd behavior. The encoding of the PHP file is UTF-8, server is running Ubuntu 14.04 with PHP 5.4 as a Apache 2.4 module inside a Vagrant environment.

What may be the cause of this? I read about issues with the HTML entity & instead of plain &'s, but that doesn't seem to apply here.

UPDATE

I just ran the same code on the command line in interactive mode via SSHing into the Vagrant machine. In interactive mode parse_str works without problem! I then ran my test script from the command line via $ php /var/www/test.php which also worked properly. Is this a problem with the Apache PHP module or configuration?

  • 写回答

1条回答 默认 最新

  • dongza1708 2014-11-16 21:11
    关注

    Notice how your strings are split on both & and a?

    I think the configuration setting arg_separator.input is incorrectly set to "&" instead of the default "&".

    This setting can be set in php.ini, .htaccess, httpd.conf or .user.ini. See: Where a configuration setting may be set.

    Test program:

    <?php
    
      echo "arg_separator.input = '", ini_get ('arg_separator.input'), "'
    ";
    
      $content = "first=value&arr[]=foo+bar&arr[]=baz";
      parse_str($content, $parsedParams);
    
      var_dump ($parsedParams);
    

    Output (somewhat compacted) with different settings in php.ini:

    arg_separator.input = '&'
    array(2) {
      ["first"] => string(5) "value"
      ["arr"] => array(2) {
        [0] => string(7) "foo bar"
        [1] => string(3) "baz"
      }
    }
    
    arg_separator.input = '&amp;'
    array(5) {
      ["first"] => string(1) "v"
      ["lue"] => string(0) ""
      ["rr"] => array(2) {
        [0] => string(5) "foo b"
        [1] => string(1) "b"
      }
      ["r"] => string(0) ""
      ["z"] => string(0) ""
    }
    

    The configuration setting arg_separator.output also defaults to "&". Setting this to "&amp;" might be okay if you only produce HTML output. But you will run into trouble if you want to use http_build_query() to produce an HTTP Location: header, or in other situations where an HTML entity reference is not suitable.

    Test program:

    <?php
    
      echo "arg_separator.output = '", ini_get ('arg_separator.output'), "'
    ";
    
      $q = http_build_query (array ('a' => 0, 'b' => 1, 'c' => 2));
      echo $q, "
    ";
    

    Output with different settings in php.ini:

    arg_separator.output = '&'
    a=0&b=1&c=2
    
    arg_separator.output = '&amp;'
    a=0&amp;b=1&amp;c=2
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料