1. All elements of the $_SERVER array whose keys begin with 'HTTP_' come from HTTP request headers and are not to be trusted.

2. All HTTP headers sent to the script are made available through the $_SERVER array, with names prefixed by 'HTTP_'.

3. $_SERVER['PHP_SELF'] is dangerous if misused. If login.php/nearly_arbitrary_string is requested, $_SERVER['PHP_SELF'] will contain not just login.php, but the entire login.php/nearly_arbitrary_string. If you've printed $_SERVER['PHP_SELF'] as the value of the action attribute of your form tag without performing HTML encoding, an attacker can perform XSS attacks by offering users a link to your site such as this:

The javascript block would define an event handler function and bind it to the form's submit event. This event handler would load via an <img> tag an external file, with the submitted username and password as parameters.

Use $_SERVER['SCRIPT_NAME'] instead of $_SERVER['PHP_SELF']. HTML encode every string sent to the browser that should not be interpreted as HTML, unless you are absolutely certain that it cannot contain anything that the browser can interpret as HTML.

Remove the request_fulluri => 1 option, and $_SERVER['REQUEST_URI'] gets back to its "normal":/some_script.php

Apparently, request_fulluri is useful when using some proxy servers.

In this case, there is no proper way to "detect" if this option was set or not, and you should probably use a combination of other $_SERVER[] elements (like REQUEST_SCHEME, SERVER_NAME and SERVER_PORT) to determine if this was the case.

One quick (and improvable) way to detect it would be to compare the start of the REQUEST_URI with REQUEST_SCHEME:

Data: $_SERVER['PHP_SELF']Data type: StringPurpose: 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: YesWorks 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: StringPurpose: 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: YesWorks 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: StringPurpose: 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: YesWorks on CLI mode: No

Data: $_SERVER['REQUEST_URI']Data type: StringPurpose: 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: YesWorks on CLI mode: No

Data: $_SERVER['PATH_INFO']Data type: StringPurpose: 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 controlWorks on web mode: YesWorks on CLI mode: No

Note that 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.

Data: __FILE__Data type: StringPurpose: 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: YesWorks on CLI mode: Yes

Data: __DIR__Data type: StringPurpose: The absolute pathname to the running PHP file, excluding the filenameCaveat: 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: YesWorks on CLI mode: Yes

Data: $_SERVER['SCRIPT_FILENAME']Data type: StringPurpose: The absolute pathname of the origin PHP file, including the filenameCaveat: 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: YesWorks on CLI mode: Yes

Data: $_SERVER['PATH_TRANSLATED']Data type: StringPurpose: The absolute pathname of the origin PHP file, including the filenameCaveat: 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: YesWorks on CLI mode: No

Data: $_SERVER['DOCUMENT_ROOT']Data type: StringPurpose: 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: YesWorks on CLI mode: No

Note that 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.

When using the $_SERVER['SERVER_NAME'] variable in an apache virtual host setup with a ServerAlias directive, be sure to check the UseCanonicalName apache directive. If it is On, this variable will always have the apache ServerName value. If it is Off, it will have the value given by the headers sent by the browser.

Depending on what you want to do the content of this variable, put in On or Off.

Be warned that most contents of the Server-Array (even $_SERVER['SERVER_NAME']) are provided by the client and can be manipulated. They can also be used for injections and thus MUST be checked and treated like any other user input.

Data: $_GETData 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: YesWorks on CLI mode: No

Data: $_SERVER['QUERY_STRING']Data type: StringPurpose: 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: YesWorks on CLI mode: No

$_SERVER['DOCUMENT_ROOT'] is incredibly useful especially when working in your development environment. If you're working on large projects you'll likely be including a large number of files into your pages. For example:

In development environments, you're rarely working with your root folder, especially if you're running PHP locally on your box and using DOCUMENT_ROOT is a great way to maintain URL conformity. This will save you hours of work preparing your application for deployment from your box to a production server (not to mention save you the headache of include path failures).

Be aware that it's a bad idea to access x-forwarded-for and similar headers through this array. The header names are mangled when populating the array and this mangling can introduce spoofing vulnerabilities.

This will direct all external traffic to your home page. Of course you could send a 404 or other custom error. Best practice is not to stay on the page with a custom error message as you acknowledge that the page does exist. That's why I redirect unwanted calls to (for example) phpmyadmin.

$_SERVER['DOCUMENT_ROOT'] may contain backslashes on windows systems, and of course it may or may not have a trailing slash (backslash).I saw the following as an example of the proper way we're supposed to deal with this issue:

Ok, the latter may be used to access a file inside the parent directory of the document root, but actually does not properly address the issue.In the end, don't warry about. It should be safe to use forward slashes and append a trailing slash in all cases.Let's say we have this:

searched $_SERVER["REDIRECT_URL"] for a while and noted that it is not mentioned in php documentation page itself. look like this is only generated by apache server(not others) and using $_SERVER["REQUEST_URI"] will be useful in some cases as mine.

A way to get the absolute path of your page, independent from the site position (so works both on local machine and on server without setting anything) and from the server OS (works both on Unix systems and Windows systems).

The only parameter it requires is the folder in which you place this scriptSo, for istance, I'll place this into my SCRIPT folder, and I'll write SCRIPT word length in $conflen

<?php/* * I wrote this because I was including a file with classes in it. Let's say that * I have a contact page at mysite.com/contact/index.php and a Form class at * mysite.com/classes/Form.php. So in index.php, I have this statement: * require '../classes/Form.php'; * The Form class includes a method to generate the HTML markup for a number of * form elements, including a CAPTCHA image and associated text field. To do so, * it must generate an <img /> element and give it a src of Form.php?captcha. * But I wanted it to automatically generate a src attribute without index.php * giving it a relative path. This script comes in handy by automatically * locating the directory that contains the included file (Form.php) and converting * it from an absolute path to a relative path that could be used for an img src, * an a href, a link href, etc. */ function relativeURL () {$dir = str_replace('\\', '/', __DIR__);// Resolves inconsistency with PATH_SEPARATOR on Windows vs. Linux // Use dirname(__FILE__) in place of __DIR__ for older PHP versionsreturn substr($dir, strlen($_SERVER['DOCUMENT_ROOT']));// Clip off the part of the path outside of the document root}

If you apply redirection in ALL your requests using commands at the Apache virtual host file like:RewriteEngine OnRewriteCond "%{REQUEST_URI}" "!=/index.php"RewriteRule "^/(.*)$" "index.php?$1" [NC,NE,L,QSA]you should expect some deviations in your $_SERVER global.

Now your $_SERVER global contains among others:'REQUEST_URI' => '/a/b?x=1&y=2', it retains the initial url after the host 'QUERY_STRING' => 'a/b&x=1&y=2', notice how php replaces '?' with '&' 'SCRIPT_NAME' => '/index.php', as it was intended to be.

Tech note:$_SERVER['argc'] and $_SERVER['argv'][] has some funny behaviour,used from linux (bash) commandline, when called like "php ./script_name.php 0x020B" there is everything correct, but "./script_name.php 0x020B"is not correct - "0" is passed instead of "0x020B" as $_SERVER['argv'][1] - see the script below.Looks like the parameter is not passed well from bash to PHP.(but, inspected on the level of bash, 0x020B is understood well as $1)

Note that, in Apache 2, the server settings will affect the variables available in $_SERVER. For example, if you are using SSL, the following directive will dump SSL-related status information, along with the server certificate and client certificate (if present) into the $_SERVER variables:

It makes sense to want to paste the $_SERVER['REQUEST_URI'] on to a page (like on a footer), but be sure to clean it up first with htmlspecialchars() otherwise it poses a cross-site scripting vulnerability.

Please note on Windows/IIS - the variable 'USER_AUTH' will return the username/identity of the user accessing the page, i.e. if anonymous access is off, you would normally get back "$domain\$username".

$_SERVER['DOCUMENT_ROOT'] in different environments may has trailing slash or not, so be careful when including files from $_SERVER['DOCUMENT_ROOT']:<?phpinclude(dirname($_SERVER['DOCUMENT_ROOT']) . DIRECTORY_SEPARATOR . 'file.php')?>

If you have some PHP code or file that is included from within a web request via Apache + PHP, as well as from a command line script, be very careful to inspect the keys inside of $_SERVER that you intend to use.

The keys and values are different, and in fact, it also matters if you are running as your_user, sudo php from your_user, or from root.

For example, I just found out that $_SERVER['PWD'] is not available if you run from the command line via sudo (PHP 5.2x, CentOS, YMMV).

To make a test, create a file called server.php with the following content:

Now you can diff the output of each of these three files and inspect against what you get when viewing the $_SERVER section of phpinfo() from a web request. You may find the differences to be quite striking, in all, four different ways to run the same PHP file!

'HTTPS' Set to a non-empty value if the script was queried through the HTTPS protocol. Note that when using ISAPI with IIS, the value will be off if the request was not made through the HTTPS protocol.

Please note, you have to check additional the result! Because the header may be missing or another possible thing, it is malformed. So check the result with a list with languages you support and perhaps you have to load a default language.

For an hosting that use windows I have used this script to make REQUEST_URI to be correctly setted on IIS<?phpfunction request_URI() { if(!isset($_SERVER['REQUEST_URI'])) {$_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME']; if($_SERVER['QUERY_STRING']) {$_SERVER['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING']; } } return $_SERVER['REQUEST_URI'];}$_SERVER['REQUEST_URI'] = request_URI();?>