当前位置: 动力学知识库 > 问答 > 编程问答 >

php - PHP5.4 "parse_str" behaving unexpectedly

问题描述:

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?

网友答案:

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'), "'\n";

  $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'), "'\n";

  $q = http_build_query (array ('a' => 0, 'b' => 1, 'c' => 2));
  echo $q, "\n";

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
分享给朋友:
您可能感兴趣的文章:
随机阅读: