php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #74424 $_SERVER documentation page needs improvement.
Submitted: 2017-04-12 23:25 UTC Modified: 2017-04-13 00:55 UTC
From: chris at ocproducts dot com Assigned:
Status: Open Package: Variables related
PHP Version: Irrelevant OS:
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2017-04-12 23:25 UTC] chris at ocproducts dot com
Description:
------------
I spent considerable time trying to improve this page because honestly it's woefully insufficient. However, my comments are too big for a note. Maybe these can be worked into the page, as a new section.

My comments follow...


These settings can be very subtle and tricky, even for people using PHP a long time, so I'll re-summarise them, and some ones documented elsewhere.

By "origin PHP file" I mean what is initially called by the PHP interpretor. By "running PHP file" I mean whatever is currently active in the execution context (usually an include).

Data: __FILE__
Data type: String
Purpose: The absolute pathname of the running PHP file, including the filename.
Caveat: This is not the file called by the PHP processor, it's what is running. So if you are inside an include, it's the include.
Caveat: Symbolic links are pre-resolved, so don't trust comparison of paths to be accurate.
Caveat: Don't assume all operating systems use '/' for the directory separator.
Works on web mode: Yes
Works on CLI mode: Yes

Data: __DIR__
Data type: String
Purpose: The absolute pathname to the running PHP file, excluding the filename
Caveat: This is not the file called by the PHP processor, it's what is running. So if you are inside an include, it's the include.
Caveat: Symbolic links are pre-resolved, so don't trust comparison of paths to be accurate.
Caveat: Don't assume all operating systems use '/' for the directory separator.
Works on web mode: Yes
Works on CLI mode: Yes

Data: $_SERVER['SCRIPT_FILENAME']
Data type: String
Purpose: The absolute pathname of the origin PHP file, including the filename
Caveat: Not set on all PHP environments, may need setting by copying from __FILE__ before other files are included.
Caveat: Symbolic links are not pre-resolved, use PHP's 'realpath' function if you need it resolved.
Caveat: Don't assume all operating systems use '/' for the directory separator.
Caveat: "Filename" makes you think it is just a filename, but it really is the full absolute pathname. Read the identifier as "Script's filesystem (path)name".
Works on web mode: Yes
Works on CLI mode: Yes

Data: $_SERVER['PATH_TRANSLATED']
Data type: String
Purpose: The absolute pathname of the origin PHP file, including the filename
Caveat: It's probably not set, best to just not use it. Just use realpath($_SERVER['SCRIPT_FILENAME']) (and be aware that itself may need to have been emulated).
Caveat: Symbolic links are pre-resolved, so don't trust comparison of paths to be accurate.
Caveat: Don't assume all operating systems use '/' for the directory separator.
Works on web mode: Yes
Works on CLI mode: No

Data: $_SERVER['PHP_SELF']
Data type: String
Purpose: The URL path name of the current PHP file, including path-info (see $_SERVER['PATH_INFO']) and excluding URL query string. Includes leading slash.
Caveat: This is after URL rewrites (i.e. it's as seen by PHP, not necessarily the original call URL).
Works on web mode: Yes
Works on CLI mode: Tenuous (emulated to contain just the exact call path of the CLI script, with whatever exotic relative pathname you may call with, not made absolute and not normalised or pre-resolved)

Data: $_SERVER['SCRIPT_NAME']
Data type: String
Purpose: The URL path name of the current PHP file, excluding path-info and excluding URL query string. Includes leading slash.
Caveat: This is after URL rewrites (i.e. it's as seen by PHP, not necessarily the original call URL).
Caveat: Not set on all PHP environments, may need setting via preg_replace('#\.php/.*#', '.php', $_SERVER['PHP_SELF']).
Works on web mode: Yes
Works on CLI mode: Tenuous (emulated to contain just the exact call path of the CLI script, with whatever exotic relative pathname you may call with, not made absolute and not normalised or pre-resolved)

Data: $_SERVER['REDIRECT_URL']
Data type: String
Purpose: The URL path name of the current PHP file, path-info is N/A and excluding URL query string. Includes leading slash.
Caveat: This is before URL rewrites (i.e. it's as per the original call URL).
Caveat: Not set on all PHP environments, and definitely only ones with URL rewrites.
Works on web mode: Yes
Works on CLI mode: No

Data: $_SERVER['REQUEST_URI']
Data type: String
Purpose: The URL path name of the current PHP file, including path-info and including URL query string. Includes leading slash.
Caveat: This is before URL rewrites (i.e. it's as per the original call URL). *
*: I've seen at least one situation where this is not true (there was another $_SERVER variable to use instead supplied by the URL rewriter), but the author of the URL rewriter later fixed it so probably fair to dismiss this particular note.
Caveat: Not set on all PHP environments, may need setting via $_SERVER['REDIRECT_URL'] . '?' . http_build_query($_GET) [if $_SERVER['REDIRECT_URL'] is set, and imperfect as we don't know what GET parameters were originally passed vs which were injected in the URL rewrite] --otherwise-- $_SERVER['PHP_SELF'] . '?' . http_build_query($_GET).
Works on web mode: Yes
Works on CLI mode: No

Data: $_SERVER['PATH_INFO']
Data type: String
Purpose: Find the path-info, which is data after the .php filename in the URL call. It's a strange concept.
Caveat: Some environments may not support it, it is best avoided unless you have complete server control
Works on web mode: Yes
Works on CLI mode: No

Data: $_GET
Data type: Array (map)
Purpose: Contains all GET parameters (i.e. a parsed URL query string).
Caveat: GET parameter names have to be compliant with PHP variable naming, e.g. dots are not allowed and get substituted.
Works on web mode: Yes
Works on CLI mode: No

Data: $_SERVER['QUERY_STRING']
Data type: String
Purpose: Gets an unparsed URL query string.
Caveat: Not set on all PHP environments, may need setting via http_build_query($_GET).
Works on web mode: Yes
Works on CLI mode: No

Data: $_SERVER['argv']
Data type: Array (list)
Purpose: Get CLI call parameters.
Works on web mode: Tenuous (just contains a single parameter, the query string)
Works on CLI mode: Yes

Data: $_SERVER['DOCUMENT_ROOT']
Data type: String
Purpose: Get the absolute path to the web server's document root. No trailing slash.
Caveat: Don't trust this to be set, or set correctly, unless you control the server environment.
Caveat: May or may not have symbolic links pre-resolved, use PHP's 'realpath' function if you need it resolved.
Caveat: Don't assume all operating systems use '/' for the directory separator.
Works on web mode: Yes
Works on CLI mode: No


Note that some that don't work on CLI mode may also not work on various exotic web server environments, depending on how they are set up. Over the years I've seen weirdness on IIS, Google AppEngine, alternative PHP implementations, and other exotic servers like Xitami. If you require code to work on diverse systems it's good to create a cleanup layer that derives missing settings from known ones. I've tried to identify above where things may be missing and how to recreate them. If something is not set it may be missing from $_SERVER, or it may be blank, so use PHP's 'empty' function for your test.

Note that if you call "php --info" on the command line then naturally some of these settings are going to be blank, as no PHP file is involved.



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-04-12 23:39 UTC] chris at ocproducts dot com
I'll chop it into sections for now and add as separate notes, as I appreciate incorporating this formally is going to take a bit more time.
 [2017-04-12 23:40 UTC] chris at ocproducts dot com
I also advise cross-referencing these 2 pages:

http://php.net/manual/en/language.constants.predefined.php
http://php.net/manual/en/reserved.variables.server.php
 [2017-04-12 23:48 UTC] requinix@php.net
-Status: Open +Status: Feedback -Package: Documentation problem +Package: Variables related
 [2017-04-12 23:48 UTC] requinix@php.net
It sounds like you've got a set of changes in mind? How about using the online editor via the Edit link in the top-right corner of the page?
https://edit.php.net/?project=PHP&perm=en/reserved.variables.server.php
If you use that to submit a patch with your improvements then someone will be able to see and accept it without much work (at least on their part).

But __FILE__, __DIR__, and $_GET really should not be documented on this page. They have their own pages and talking about them here creates a conflict. Use links like the page is doing now.
 [2017-04-13 00:49 UTC] chris at ocproducts dot com
Thanks requinix.

I've decided splitting up and adding as notes is sufficient. It would be a lot of work to get them into the page neatly, as I structured it all very differently to how the page is now.
And as you say, I am mixing stuff from 2 pages. That's good for the reader I have in mind, but bad for the current documentation structure.

However, adding those cross-links would definitely be a good idea IMO. A very simple thing to let people see that there are 2 different sets of path 'variables' available to them, which isn't currently obvious when reading these individual pages.

So I suggest adding the cross-links, then this can be marked resolved. I don't have the time right now to get into a PHP patch submitting workflow, but someone used to editing docs can do in 3 mins ;-).
 [2017-04-13 00:55 UTC] requinix@php.net
-Status: Feedback +Status: Open
 
PHP Copyright © 2001-2018 The PHP Group
All rights reserved.
Last updated: Tue Nov 13 20:01:26 2018 UTC