Edit report at https://bugs.php.net/bug.php?id=55208&edit=1
ID: 55208 User updated by: loco at andrews dot lv Reported by: loco at andrews dot lv Summary: setting correct SCRIPT_NAME vs PHP_SELF is impossible in certain circumstances Status: Assigned Type: Bug Package: FPM related Operating System: Gentoo Linux (2.6.39-gentoo-r3) PHP Version: 5.3.6 Assigned To: fat Block user comment: N Private report: N New Comment: Jerome, thanks for looking into this issue. The main trouble is that sometimes, even for FCGI/FPM SAPI both SCRIPT_NAME and PHP_SELF must refer to the original URI, and *NOT* to SCRIPT_FILENAME! This behaviour is desired, for example, in order to support older eZPublish or vTiger CRM code that relies on PHP_SELF and assumes it contains the original URI, not the SCRIPT_FILENAME, which would be /index.php. So, I thought it would be as simple as this: fastcgi_param PHP_SELF $uri; fastcgi_param SCRIPT_NAME $uri; Apparently, it isn't, and PHP-FPM adjusts these variables by itself, even though they are submitted via server environment. I've been experiencing situations when PHP_SELF would contain a double path, or that PHP_SELF would contain /index.php/, but all I need both to contain is the original URI without arguments. In addition, when cgi.fix_pathinfo is set to 0, I am not able to access any PHP scripts as I get "No input file specified" response in the browser. Please additionally notice that your suggestion with fastgi_split_path_info doesn't work, no matter which value cgi.fix_pathinfo is set to, as PATH_INFO/PATH_TRANSLATED remain empty. Previous Comments: ------------------------------------------------------------------------ [2011-07-17 10:55:31] f...@php.net As described in http://php.net/manual/en/reserved.variables.server.php 'PHP_SELF': The filename of the currently executing script, relative to the document root. For instance, $_SERVER['PHP_SELF'] in a script at the address http://example.com/test.php/foo.bar would be /test.php/foo.bar whereas 'SCRIPT_NAME': Contains the current script's path.(without further details). If we look into the code of differents SAPIs, here what's done: apache2handler: PHP_SELF is set REQUEST_URI given by apache. So it should be /test.php/foo.bar cgi/fpm (the code for this part is the same): PHP_SELF is set to REQUEST_URI if cgi.fix_pathinfo is 0. PHP_SELF is set to SCRIPT_NAME if cgi.fix_pathinfo is 1. this cgi.fix_pathinfo is a real mess (see https://bugs.php.net/bug.php?id=51983). I don't really know what to think about all this right now ... ------------------------------------------------------------------------ [2011-07-17 09:11:42] loco at andrews dot lv > 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. I know, but if I don't set PHP_SELF to $uri, then older PHP scripts that haven't been written for FastCGI mode and that require that PHP_SELF refers to the URI, as in mod_php/apache case, won't work! So I *need* to set both SCRIPT_NAME and PHP_SELF to $uri actually. Andrejs ------------------------------------------------------------------------ [2011-07-17 09:06:32] loco at andrews dot lv I tried your suggestion and it doesn't set PATH_INFO correctly: Accessing "http://testsite.com/test/test%20test": Array ( [SCRIPT_FILENAME] => /opt/www/testsite.com/index.php [REQUEST_URI] => /test/test%20test [PATH_INFO] => [PATH_TRANSLATED] => /opt/www/testsite.com [PHP_SELF] => /index.php [SCRIPT_NAME] => /index.php ) PATH_INFO should be set to "/test/test%20test/", i believe? Andrejs ------------------------------------------------------------------------ [2011-07-17 08:47:05] f...@php.net 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 ------------------------------------------------------------------------ [2011-07-17 08:02:25] loco at andrews dot lv 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>'; ?> ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at https://bugs.php.net/bug.php?id=55208 -- Edit this bug report at https://bugs.php.net/bug.php?id=55208&edit=1