|   | php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
| 
  [2011-07-14 15:55 UTC] loco at andrews dot lv
 Description:
------------
I am running nginx 1.0.4 with php-fpm and php 5.3.6.
It seems that PHP_SELF has strong dependency on the setting of SCRIPT_NAME.  
When setting SCRIPT_NAME to something, $_SERVER['PHP_SELF'] will contain 
PHP_SELF environment value concatenated with environment value of SCRIPT_NAME.  
If SCRIPT_NAME is not set to anything, then $_SERVER['PHP_SELF'] contains what 
is passed to the environment, however, since SCRIPT_NAME is not set, PHP scripts 
that rely on SCRIPT_NAME will not work. 
Example #1:
accessing URL:  /index.php/some/url
setting server variables:
SCRIPT_NAME /some/url
PHP_SELF /some/url
result:
print $_SERVER['SCRIPT_NAME']; // outputs: "/some/url"  - OK
print $_SERVER['PHP_SELF']; // outputs: "/some/url//some/url" - NOT OK!
Example #2:
SCRIPT_NAME (unset)
PHP_SELF /some/url
result:
print $_SERVER['SCRIPT_NAME'];  // outputs: ""
print $_SERVER['PHP_SELF']; // outputs: "/some/url"
Example #3:
SCRIPT_NAME /some/url
PHP_SELF (unset)
result:
print $_SERVER['SCRIPT_NAME'];  // outputs: "/some/url"
print $_SERVER['PHP_SELF'];  // outputs: ""
---
Bottom line: if configured as demonstrated in the first example, scripts that 
rely on SCRIPT_NAME will work properly, but scripts that require PHP_SELF won't 
work, as it contains the invalid URL;  if configured as shown in the second 
example, scripts that rely on PHP_SELF work properly, but scripts that require 
SCRIPT_NAME, don't work at all;  lastly, if configured as in the third example, 
scripts that use SCRIPT_NAME will work properly, but scripts that use PHP_SELF 
won't work, as PHP_SELF is empty.
Any workaround for this issue?  
When using mod_php with apache, both SCRIPT_NAME and PHP_SELF can be set to the 
same value, and will be interpreted by PHP exactly like they are passed.  
However, in FCGI/PHP-FPM environment I cannot find a way to set them both to the 
same value! 
How is $_SERVER['PHP_SELF'] being constructed?  
Why should it rely on SCRIPT_NAME at all?  
How to set server environment correctly, so it is the same under FastCGI and 
under mod_php / apache 2.2?
Andrejs
Test script:
---------------
<?php
   print '<pre>';
   printf("SCRIPT_NAME: \"%s\"\n", $_SERVER['SCRIPT_NAME']);
   printf("PHP_SELF:    \"%s\"\n", $_SERVER['PHP_SELF']);
   print '</pre>';
?>
Expected result:
----------------
I'd thought PHP_SELF should be possible to define explicitly through the server 
environment, without other variables affecting it's value.  How come is it so that 
in the apache/mod_php mode both SCRIPT_NAME and PHP_SELF contain the same value?  
This does not seem to be possible in the FastCGI environment, at least when using 
php-fpm.  
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits             | |||||||||||||||||||||||||||||||||||||
|  Copyright © 2001-2025 The PHP Group All rights reserved. | Last updated: Fri Oct 31 02:00:02 2025 UTC | 
Hi Jerome, I hope the information is now sufficient: ### nginx.conf: # http part with fastcgi configuration: http { fastcgi_pass_request_headers on; fastcgi_intercept_errors on; fastcgi_buffer_size 4k; fastcgi_buffers 1024 4k; index index.html; } # virtual host definition server { listen 80; server_name .mysite.com; access_log /var/log/nginx/mysite.access_log main; error_log /var/log/nginx/mysite.error_log warn; root /opt/www/mysite.com; location / { index index.php; } # if the request file name contains one of the below extensions, # serve it directly if ($request_filename ~* \.(css|js|ico|gif|png|bmp|jpe? g|tiff?)$) { break; } # otherwise, /index.php handles the request rewrite ^(.*)$ /index.php$1 last; location ~ ^(?<SCRIPT_FILENAME>.+\.php)(?<PATH_INFO>.*)$ { include fastcgi_params; fastcgi_param PATH_INFO $PATH_INFO; fastcgi_param PATH_TRANSLATED $document_root$PATH_INFO; fastcgi_param SCRIPT_FILENAME $document_root$SCRIPT_FILENAME; # Attention! Both PHP_SELF and SCRIPT_NAME must contain the same value, # but they don't! fastcgi_param PHP_SELF $uri; fastcgi_param SCRIPT_NAME $uri; # set SCRIPT_URL/SCRIPT_URI for compatibility fastcgi_param SCRIPT_URL $PATH_INFO; fastcgi_param SCRIPT_URI $scheme://$http_host$PATH_INFO; fastcgi_param PHP_VALUE "include_path=$document_root:$document_root/include"; try_files $SCRIPT_FILENAME =404; fastcgi_pass unix:/var/run/fastcgi/php-fpm.sock; } } ### php-fpm.conf ;;;;;;;;;;;;;;;;;;;;; ; FPM Configuration ; ;;;;;;;;;;;;;;;;;;;;; [global] pid = /var/run/php-fpm.pid error_log = /var/log/php-fpm.log log_level = debug emergency_restart_threshold = 7 emergency_restart_interval = 2 ;;;;;;;;;;;;;;;;;;;; ; Pool Definitions ; ;;;;;;;;;;;;;;;;;;;; [www] ; pool www listen = /var/run/fastcgi/php-fpm.sock ;listen.backlog = -1 listen.backlog = 4096 ;listen.allowed_clients = 127.0.0.1 listen.owner = www listen.group = www ;listen.mode = 0660 user = www group = www pm = dynamic pm.max_children = 100 pm.start_servers = 2 pm.min_spare_servers = 2 pm.max_spare_servers = 4 pm.max_requests = 500 pm.status_path = /fpm-status-1 request_terminate_timeout = 3605 request_slowlog_timeout = 30 slowlog = /var/log/php-fpm-slow.log catch_workers_output = yes env[HOSTNAME] = $HOSTNAME ### php.ini # scripts simply don't work with cgi.fix_pathinfo=0 # nginx reporting "404 File not found" when set to 0 # I don't use cgi.fix_pathinfo actually, since # I parse SCRIPT_FILENAME and PATH_INFO directly # in the nginx location block (see nginx.conf) # with PCRE capturing cgi.fix_pathinfo=1 ## test case: index.php <?php # prints out $_SERVER environment variables # please check SCRIPT_NAME and PHP_SELF ! print '<pre>'; print_r($_SERVER); print '</pre>'; ?>SCRIPT_NAME is already defined in the fastcgi_params file. PHP_SELF doesn't have to be set in nginx as it's made in FPM. Can you try the following nginx configuration please ? location ~ ^.+\.php { include fastcgi_params; fastcgi_split_path_info ^(.+\.php)(.*)$; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; vastcgi_param PHP_VALUE "include_path=$document_root:$document_root/include"; fastcgi_pass unix:/var/run/fastcgi/php-fpm.sock; try_files fastcgi_script_name =404; } it should be exactly the same as your configuration and it sould work. thx ++ jerome