Fix Empty $_REQUEST Array in Nginx with PHP-FPM: Troubleshooting Guide


9 views

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