[PHP-DEV] PHP_SELF variable in cgi mode - patch proposition

0 views
Skip to first unread message

Piotr Klaban

unread,
Sep 20, 2002, 4:13:27 AM9/20/02
to

I have seen the same problem reported repeatedly on bug tracking system:
in php-cgi mode PHP_SELF is copied from PATH_INFO -> in standard cgi mode it is useless
(for example bug report see http://bugs.php.net/bug.php?id=18942&edit=1)

... and all the bug reports are , mostly because of no user feedback,
and the problem is so clear that user feedback is not even necessary.

You can see the problem when you run a cgi script with two lines:

<standard cgi script>
#!/usr/bin/php
<?php phpinfo() ?>
</standard cgi script>

- PHP_SELF variable would not contain script name.

I will try to prove that current behaviour of PHP should be modified.

PHP_SELF variable - what is it for?
-----------------------------------

<manual>
PHP_SELF
The filename of the currently executing script, relative to the document
root. If PHP is running as a command-line processor, this variable is not
available. This variable will include path information if present
(e.g. $PHP_SELF on this address: "http://example.com/test.php/foo.bar"
would be "/test.php/foo.bar")
</manual>

PHP_SELF is normaly used as a self-referencing URL. But it would only
work in apache-mod and in specific situation when php is a cgi-wrapper.
When you run standard cgi script as http://example.com/test.php/foo.bar.cgi
$PHP_SELF is empty (because PATH_INFO is empty).

The reason why PATH_INFO is the source for PHP_SELF in cgi mode is that
(I think, I did not tested it) Windows' Apache edition uses PHP as a php wrapper. In this case
php cgi api should be called php-cgiwrap api, and in this situation
PATH_INFO contains script name. But normally PHP_SELF do not need to be equal
to PATH_INFO. The purpose of PHP_SELF variable is just self-referencing
and it should contain script URL and optional path info.

Then, because current bevaviour of php is inconsistent,
you have to do something:
-------------------------
a) write it cleanly in the manual:
'$PHP_SELF is useless in cgi "non-wrapper with php" mode, use other env. variables,
e.g. $_SERVER['SCRIPT_URL'] if you use Apache'
b) change php source in such a way, that manual description whould be correct

If you choose a) - it would be OK to me, and many users would not be surprised at php behaviour,

If you choose b) - read on:

The referenced URL suggest to change cgi_main.c:

<bug.php?id=18942>
The code in question is in sapi/cgi/cgi_main.c :

SG(request_info).request_uri = getenv("PATH_INFO");
if (!SG(request_info).request_uri) {
SG(request_info).request_uri = getenv("SCRIPT_NAME");
}

Should be more like :

SG(request_info).request_uri = getenv("SCRIPT_NAME");
strcat(SG(request_info).request_uri, getenv("PATH_INFO"));
</bug.php>

but this would not work with Apache + cgiwrap-php (http://cgiwrap.sourceforge.net/ - use cvs version)
because (taken from http://httpd.apache.org/docs/mod/mod_rewrite.html):

<mod_rewrite page>
environment variables named SCRIPT_URL and SCRIPT_URI. These contain the logical Web-view
to the current resource, while the standard CGI/SSI variables SCRIPT_NAME and SCRIPT_FILENAME
contain the physical System-view.

SCRIPT_NAME=/sw/lib/w3s/tree/global/u/rse/.www/index.html
SCRIPT_FILENAME=/u/rse/.www/index.html
SCRIPT_URL=/u/rse/
SCRIPT_URI=http://en1.engelschall.com/u/rse/
</mod_rewrite>

My own example for Apache + cgiwrap + standard-cgi-script-running-php :

<exp alt="username and virtual server name is changed">
SCRIPT_NAME=/cgi-bin/cgiwrap/username/t/php-exp.cgi
SCRIPT_FILENAME=/home/username/WWW/t/php-exp.cgi
PATH_INFO=/test/
PHP_SELF=/test/
REQUEST_URI=/t/php.cgi/test/?test
REDIRECT_URL=/t/php.cgi/test/
SCRIPT_URI=http://www.canonicalvirtualserver.com/t/php.cgi/test/
SCRIPT_URL=/t/php.cgi/test/
</exp>

Then under Apache for self-referencing address you should use
SCRIPT_URL variable.

Then my proposition for changing cgi_main.c is:

<change proposition no. 1>
SG(request_info).request_uri = getenv("SCRIPT_URL");
if (!SG(request_info).request_uri) {
SG(request_info).request_uri = getenv("PATH_INFO");
if (!SG(request_info).request_uri) {
SG(request_info).request_uri = getenv("SCRIPT_NAME");
}
}
</change>

or alternatively you can check if PATH_INFO has zero length:

<change proposition no. 2>
SG(request_info).request_uri = getenv("SCRIPT_URL");
if (!SG(request_info).request_uri) {
SG(request_info).request_uri = getenv("PATH_INFO");
if (!SG(request_info).request_uri || (SG(request_info).request_uri)[0] == '\0') {
SG(request_info).request_uri = getenv("SCRIPT_NAME");
}
}
</change>

Best regards,

--
Piotr Klaban

--
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Piotr Klaban

unread,
Sep 20, 2002, 6:29:35 AM9/20/02
to
On Fri, Sep 20, 2002 at 11:24:43AM +0200, Arkadiusz Góralski wrote:
> > I have seen the same problem reported repeatedly on bug tracking system:
> > in php-cgi mode PHP_SELF is copied from PATH_INFO -> in standard cgi mode
> > it is useless (for example bug report see
> > http://bugs.php.net/bug.php?id=18942&edit=1)
>
> You can always use $argv[0] as described here:
> http://www.php.net/manual/en/printwn/features.commandline.php

1. Not always, as it is stated on mentioned web page:

You will only be able to use $argc and $argv if you have in php.ini:
register_globals = On
register_argc_argv = On

and I hardly know that, because of that I have lost php-contest (klondike)
because register_argc_argv was set to off on the test system, but ...
nevermind.

2. $argv[0] in PHP contains QUERY_STRING when you execute cgi script from the apacher server

<cgi_main.c from php 4.2.2>
437 if (getenv("SERVER_SOFTWARE")
438 || getenv("SERVER_NAME")
439 || getenv("GATEWAY_INTERFACE")
440 || getenv("REQUEST_METHOD")) {
441 cgi = 1;
442 if (argc > 1) {
443 argv0 = strdup(argv[1]);
^^^^^^^^^^^^^^^^^^^^^^^^
444 } else {
445 argv0 = NULL;
446 }
447 }
</cgi_main.c>

Summary: argv[0] is not a solution to the problem.

Reply all
Reply to author
Forward
0 new messages