Here's the scenario we're investigating:
The form submits correctly according to HTTP headers:
Content-Type: application/x-www-form-urlencoded
Content-Length: 51
test%5B1%5D=a&test%5B2%5D=b&test%5B3%5D=c&action=Go
But PHP receives it as:
array(2) {
["test"]=>
string(0) ""
["action"]=>
string(2) "Go"
}
string(16) "test=&action=Go&"
After extensive testing, we identified the pattern:
- Works on Windows servers
- Fails on Ubuntu with PHP 5.2.4 + Suhosin
- Works on some Ubuntu/Suhosin configurations
The working vs non-working php.ini comparison shows:
270c270
< memory_limit = 32M
---
> memory_limit = 16M
415c415
< variables_order = "EGCSP"
---
> variables_order = "EGPCS"
491d490
< include_path = ".:"
1253a1253,1254
> extension=mcrypt.so
Option 1: Manually parse the input
// Parse the raw input data
$input = file_get_contents("php://input");
parse_str($input, $_POST);
Option 2: Disable Suhosin's variable filtering
; In php.ini or .htaccess
suhosin.post.max_vars = 0
suhosin.request.max_vars = 0
Option 3: Change array naming convention
<!-- Instead of test[1], use: -->
<input type="text" name="test_1" />
The issue stems from Suhosin's aggressive input filtering combined with PHP's variable parsing. When receiving array-style form names (test[1]), Suhosin's security layer may incorrectly sanitize the input before PHP processes it, especially when:
- variables_order doesn't include POST data (P)
- Suhosin's max_vars limits are too restrictive
- There are conflicts with multipart form handling
For mission-critical applications, implement this comprehensive solution:
function get_safe_post_data() {
$input = file_get_contents("php://input");
// Handle both application/x-www-form-urlencoded and multipart/form-data
if (empty($_POST) && !empty($input)) {
if (strpos($_SERVER['CONTENT_TYPE'], 'multipart/form-data') !== false) {
// Handle file uploads specially
return array_merge($_POST, $_FILES);
} else {
parse_str($input, $result);
return $result;
}
}
return $_POST;
}
// Usage:
$cleanPost = get_safe_post_data();
I recently encountered a puzzling scenario where form data submitted via POST wasn't properly populating the $_POST array. Here's the exact situation:
";
var_dump($_POST);
var_dump(file_get_contents("php://input"));
echo "
";
?>
The issue manifests differently across environments:
- Windows servers: Works correctly
- Ubuntu with PHP 5.2.4 + Suhosin: Fails
- Another Ubuntu with same PHP/Suhosin: Works
Using Live HTTP Headers, we can see the data is actually being sent:
Content-Type: application/x-www-form-urlencoded Content-Length: 51 test%5B1%5D=a&test%5B2%5D=b&test%5B3%5D=c&action=Go
The php.ini comparison revealed:
270c270 < memory_limit = 32M --- > memory_limit = 16M 415c415 < variables_order = "EGCSP" --- > variables_order = "EGPCS" 491d490 < include_path = ".:"
Here are some approaches that might help:
// Alternative parsing method
function parse_raw_http_request(array &$a_data)
{
$input = file_get_contents('php://input');
preg_match_all('/&([^=]+)=([^&]*)/', $input, $matches);
foreach ($matches[1] as $i => $name) {
$a_data[$name] = urldecode($matches[2][$i]);
}
}
Or try modifying the form encoding:
The Suhosin patch might be interfering with array variable parsing. Try these:
- Disable Suhosin temporarily
- Check Suhosin's
suhosin.post.max_array_depth
setting - Verify
suhosin.post.max_vars
isn't too low
For immediate results:
// Temporary solution
$post_data = parse_str(file_get_contents("php://input"), $_POST);
But the proper fix involves:
- Upgrading PHP to a newer version
- Reviewing Suhosin configuration
- Testing with different content types