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] [email protected]
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] [email protected]
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