When migrating from Apache to Nginx, many PHP developers encounter this puzzling issue where $_GET, $_POST, and $_REQUEST arrays mysteriously become empty. The problem typically occurs when PHP runs as FastCGI (PHP-FPM) under Nginx without proper configuration.
The root cause usually lies in how Nginx passes request parameters to PHP-FPM. Unlike Apache's mod_php which automatically parses request bodies, Nginx requires explicit configuration to forward these parameters.
# Typical problematic Nginx location block
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
include fastcgi_params;
}
You need to modify your Nginx configuration to properly handle request parameters:
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
include fastcgi_params;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
# Specifically for POST data
fastcgi_param PHP_VALUE "post_max_size=20M \n upload_max_filesize=20M";
fastcgi_read_timeout 300;
}
Create a simple test script to verify the fix:
<?php
// test_request.php
echo "GET: ";
print_r($_GET);
echo "\n\nPOST: ";
print_r($_POST);
echo "\n\nREQUEST: ";
print_r($_REQUEST);
?>
Test with both GET and POST requests:
# GET test
curl "http://localhost/test_request.php?test=123"
# POST test
curl -X POST -d "post_data=example" http://localhost/test_request.php
If the problem persists after these changes, check these aspects:
- Verify PHP-FPM is actually running:
systemctl status php7.4-fpm
- Ensure the php.ini
variables_order
contains "GP" (GET, POST) - Check for conflicting Nginx rewrite rules that might strip parameters
- Inspect Nginx and PHP-FPM error logs for clues
While fixing the empty $_REQUEST issue, be mindful of these performance aspects:
- Using $_REQUEST combines GET, POST, and COOKIE data, which has slight overhead
- For high-performance applications, explicitly use $_GET or $_POST instead
- Consider disabling $_REQUEST entirely via php.ini:
request_order = "GP"
When migrating from Apache to Nginx, a common problem developers encounter is PHP scripts receiving empty superglobal arrays ($_REQUEST, $_GET, $_POST) despite parameters being sent through HTTP requests. This typically indicates a configuration mismatch in how Nginx passes request data to PHP-FPM.
The root cause usually lies in the fastcgi_params configuration. Unlike Apache which handles this automatically, Nginx requires explicit configuration to pass request parameters:
# Typical problematic Nginx location block location ~ \.php$ { fastcgi_pass unix:/var/run/php5-fpm.sock; include fastcgi_params; }
Add these critical parameters to your Nginx configuration:
location ~ \.php$ { fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; include fastcgi_params; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; # PHP only, required if PHP was built with --enable-force-cgi-redirect fastcgi_param REDIRECT_STATUS 200; # For handling POST data fastcgi_param PHP_VALUE "post_max_size=8M \n upload_max_filesize=8M"; }
Create a test script to verify your configuration:
<?php echo 'GET: '; print_r($_GET); echo 'POST: '; print_r($_POST); echo 'REQUEST: '; print_r($_REQUEST); // Test with: example.com/test.php?foo=bar ?>
- Missing fastcgi_split_path_info directive for clean URLs
- Incorrect permissions on PHP-FPM socket files
- Buffer size limitations in Nginx configuration
- PHP-FPM pool configuration mismatches
For production environments, consider these additional optimizations:
fastcgi_buffer_size 128k; fastcgi_buffers 4 256k; fastcgi_busy_buffers_size 256k; fastcgi_read_timeout 300; # Handle PATH_INFO properly fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_index index.php;
Remember to restart both Nginx and PHP-FPM after configuration changes:
sudo service nginx restart sudo service php-fpm restart