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

Reply via email to