|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #31843 PHP_SELF incorrect in CGI mode (same as PATH_INFO), very old bug still existing
Submitted: 2005-02-04 10:58 UTC Modified: 2005-02-05 18:30 UTC
From: ceefour at gauldong dot net Assigned:
Status: Not a bug Package: CGI/CLI related
PHP Version: 4.3.10 OS: Apache/1.3.33 (Unix) mod_ssl/2.8
Private report: No CVE-ID:
 [2005-02-04 10:58 UTC] ceefour at gauldong dot net
First of all, let me say this is a very old bug (over two years old). There are references all over the net for this, but here's what I found inside PHP's bug report:

The most related bug (actually this exact bug) is Bug #18942: $PHP_SELF is set to HTTP_SERVER_VARS[PATH_INFO] if available.

The response (which I think is pure bogus) is:
This bug has been fixed in CVS.
It's fixed in cvs as of today.
well, that "today" is somehow over two years ago. ;-)

Anyway, the problem is simple. Considering this script:

In other than CGI mode, PHP_SELF will be "/phpinfo.php/test", which is correct. But in CGI mode, PHP_SELF will be "/test", which is incorrect. Since it does not refer to the URI of the current script, but rather the PATH_INFO.

You can test it for yourself. The above URL I provided as an example is real, it's not just there for an example. So try it. You can scroll down to the the middle of the page to find out the value of PHP_SELF, but an easier and quicker way is just to look whether the PHP/Zend images load. Well, they don't, since they use PHP_SELF which has an incorrect value.

My workaround for this bug is as follows (not how handling this special quirk is *SOOOO* unnecessary):

	 * Returns URI of currently executing PHP script.
	 * I noticed some weirdness in PHP behaviour (maybe related to operating system and/or Apache version/platform).
	 * In my WinXP box PHP_SELF works fine. But in Linux production server PHP_SELF is the same as PATH_INFO
	 * and SCRIPT_URL seems to contain the real correct PHP_SELF. However, SCRIPT_URL does not exist in my WinXP box.
	 * So I guess the the only thing that is common in two servers is the REQUEST_URI server variable. So I parse
	 * this using parse_url() and returns the path portion.
	 * @access public
	 * @static This method can be called statically.
	 * @see GetServer()
	 * @return string PHP script URI.
	/*public static*/ function GetSelf() {
		if (!Types::IsEmpty($_SERVER['SCRIPT_URL'])) {
			return $_SERVER['SCRIPT_URL'];
		} else {
			$uri = $_SERVER['REQUEST_URI'];
			$parsed = @parse_url($uri);
			if (isset($parsed)) return $parsed['path'];
			else return $_SERVER['PHP_SELF'];

Reproduce code:
echo $_SERVER['PHP_SELF'];

Expected result:

Actual result:


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2005-02-04 11:47 UTC]
Check this out:

; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI.  PHP's
; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
; what PATH_INFO is.  For more information on PATH_INFO, see the cgi specs.  Setting
; this to 1 will cause PHP CGI to fix it's paths to conform to the spec.  A setting
; of zero causes PHP to behave as before.  Default is zero.  You should fix your scripts
; cgi.fix_pathinfo=0

PHP Copyright © 2001-2016 The PHP Group
All rights reserved.
Last updated: Thu Aug 25 00:01:38 2016 UTC