Nginx配置下$_SERVER['PHP_SELF']返回绝对路径问题求助
Let's break down why this is happening and how to fix it step by step.
Why $_SERVER['PHP_SELF'] Is Wrong
Your current Nginx setup has two key issues throwing off the PHP_SELF value:
- Conflicting FastCGI parameters: You're forcing
PATH_TRANSLATEDto point directly toindex.phpwhile keepingSCRIPT_FILENAMEset to the original request's file path (which doesn't exist in your public directory). This confuses PHP about the actual script context, making it use the absoluteSCRIPT_FILENAMEvalue forPHP_SELFinstead of the relative path. - Incorrect path splitting regex: Your
fastcgi_split_path_inforule^/(/.*)(/.*)$doesn't properly separate the script path from path info, which further disrupts how PHP calculates variables likePHP_SELF.
Since you're routing all legacy .php requests through Symfony's index.php (not executing them directly), the default FastCGI setup doesn't account for this proxy-like behavior.
Step-by-Step Solution
1. Update Nginx Configuration
Modify your .php location block to route all requests through index.php while preserving the original request path for PHP_SELF:
location ~* "\.php$" { # Fallback to index.php if the requested .php file doesn't exist try_files $uri /index.php$is_args$args; fastcgi_pass php-fpm:9000; include fastcgi_params; fastcgi_index index.php; # Tell PHP to execute Symfony's index.php regardless of the original request fastcgi_param SCRIPT_FILENAME $document_root/index.php; # Set SCRIPT_NAME to the original request URI (this fixes PHP_SELF) fastcgi_param SCRIPT_NAME $request_uri; # Remove these incorrect lines that were causing path confusion # fastcgi_param PATH_TRANSLATED /var/www/html/public/index.php; # fastcgi_split_path_info ^/(/.*)(/.*)$; # Keep your existing performance and timeout settings fastcgi_buffering off; fastcgi_connect_timeout 300s; fastcgi_send_timeout 300s; fastcgi_read_timeout 600s; }
2. Verify PHP's cgi.fix_pathinfo Setting
Ensure your php.ini has this setting enabled to prevent PHP from overriding path values in ways that break your legacy context:
cgi.fix_pathinfo = 0
Restart PHP-FPM after updating this setting to apply the change.
3. Safety Net: Explicitly Set PHP_SELF in Your Controller
If you still see inconsistencies, you can manually set PHP_SELF in your custom legacy controller before loading legacy files:
// In your Symfony controller that loads legacy PHP code $originalRequestUri = $_SERVER['REQUEST_URI']; $_SERVER['PHP_SELF'] = $originalRequestUri; // Load your legacy file as usual require_once $pathToLegacyFile;
This ensures your legacy code gets the exact relative path it depends on, even if Nginx parameter propagation has edge cases.
Why This Works
SCRIPT_NAMEis set to the original request URI (e.g.,/foo/bar.php), which PHP uses directly to generatePHP_SELFas the relative path your legacy code expects.SCRIPT_FILENAMEpoints to Symfony'sindex.php, so PHP executes the correct entry point while maintaining the legacy request context.- Removing the conflicting path parameters eliminates the confusion that was causing PHP to return absolute paths.
内容的提问来源于stack exchange,提问作者Dev_NIX

