©
This document uses PHP Chinese website manual Release
$_SERVER -- $HTTP_SERVER_VARS [已弃用] — 服务器和执行环境信息
$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。这个数组中的项目由 Web 服务器创建。不能保证每个服务器都提供全部项目;服务器可能会忽略一些,或者提供一些没有在这里列举出来的项目。这也就意味着大量的此类变量都会在» CGI 1.1 规范中说明,所以应该仔细研究一下。
$HTTP_SERVER_VARS 包含着相同的信息,但它不是一个超全局变量。 (注意 $HTTP_SERVER_VARS 与 $_SERVER 是不同的变量,PHP处理它们的方式不同)
在 $_SERVER 中,你也许能够,也许不能够找到下面的这些元素。注意,如果以命令行方式运行 PHP,下面列出的元素几乎没有有效的(或是没有任何实际意义的)。
Note:
如果请求方法为 HEAD,PHP 脚本将在发送 Header 头信息之后终止(这意味着在产生任何输出后,不再有输出缓冲)。
Note: 注意当使用 IIS 上的 ISAPI 方式时,如果不是通过 HTTPS 协议被访问,这个值将为 off。
Note: 你的服务器必须被配置以便产生这个变量。例如在 Apache 中,你需要在 httpd.conf 中设置 HostnameLookups On 来产生它。参见 gethostbyaddr() 。
当前执行脚本的绝对路径。
Note:
如果在命令行界面(Command Line Interface, CLI)使用相对路径执行脚本,例如 file.php 或 ../file.php,那么 $_SERVER['SCRIPT_FILENAME'] 将包含用户指定的相对路径。
Note: 自 PHP 4.3.2 起,PATH_TRANSLATED 在 Apache 2 SAPI 模式下不再和 Apache 1 一样隐含赋值,而是若 Apache 不生成此值,PHP 便自己生成并将其值放入 SCRIPT_FILENAME 服务器常量中。这个修改遵守了 CGI 规范,PATH_TRANSLATED 仅在 PATH_INFO 被定义的条件下才存在。 Apache 2 用户可以在 httpd.conf 中设置 AcceptPathInfo = On 来定义 PATH_INFO。
版本 | 说明 |
---|---|
4.1.0 | 引入 $_SERVER ,弃用 $HTTP_SERVER_VARS 。 |
Example #1 $_SERVER 范例
<?php
echo $_SERVER [ 'SERVER_NAME' ];
?>
以上例程的输出类似于:
www.example.com
Note:
“Superglobal”也称为自动化的全局变量。这就表示其在脚本的所有作用域中都是可用的。不需要在函数或方法中用 global $variable; 来访问它。
[#1] office at peername dot com [2015-11-23 10:39:26]
Keep in mind that if the user is using proxy server (like PAC), REQUEST_URI will include the full request URL like http://example.com/path/
[#2] doublecompile at gmail dot com [2015-06-24 20:32:52]
I've used the SplPriorityQueue to determine an HTTP client's preferred MIME types that are in $_SERVER['HTTP_ACCEPT'].
<?php
$queue = new \SplPriorityQueue();
foreach (preg_split('#,\s*#', $_SERVER['HTTP_ACCEPT']) as $accept) {
$split = preg_split('#;\s*q=#', $accept, 2);
$queue->insert($split[0], isset($split[1]) ? (float)$split[1] : 1.0);
}
foreach ($queue as $mime) {
echo $mime, PHP_EOL;
}
?>
My browser sends:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,**
A better example:
Accept: text/html, application/xml,text/css;q=0.4,text/plain; q=0.9, application/json;q=0.8
And this script outputs:
text/html
application/xml
text/plain
application/json
text/css
[#3] joerg dot reinholz at fastix dot org [2015-05-19 20:29:24]
On a few of servers (e.g, Strato AG Germany, shared hosting) $_SERVER["DOCUMENT_ROOT"] follow symlinks (while so configured by admins)
This is a problem while __DIR__ give the realpath. Try the error with this small script inside of DOCUMENT_ROOT:
<?php
header('Content-type: text/plain');
echo '__DIR__ : ', __DIR__ , "\n";
echo '$_SERVER["DOCUMENT_ROOT"] : ', $_SERVER["DOCUMENT_ROOT"] , "\n";
echo 'realpath($_SERVER["DOCUMENT_ROOT"]): ', realpath($_SERVER["DOCUMENT_ROOT"]), "\n";
## file 'include_me.php'
# Exit, wenn in document_root, weil dann Sicherheitsproblem auftreten kann:
if (-1 < strpos(__DIR__, $_SERVER["DOCUMENT_ROOT"]) ) {
trigger_error('Fatal: '. __FILE__
. ' darf nicht in oder unterhalb von DOCUMENT_ROOT ('
. $_SERVER["DOCUMENT_ROOT"] . ') liegen!', E_USER_ERROR);
exit;
}
?>
This will never trigger the error!
Use better:
<?php
header('Content-type: text/plain');
echo '__DIR__ : ', __DIR__ , "\n";
echo '$_SERVER["DOCUMENT_ROOT"] : ', $_SERVER["DOCUMENT_ROOT"] , "\n";
echo 'realpath($_SERVER["DOCUMENT_ROOT"]): ', realpath($_SERVER["DOCUMENT_ROOT"]), "\n";
## file 'include_me.php'
# Exit, wenn in document_root, weil dann Sicherheitsproblem auftreten kann:
if (-1 < strpos(__DIR__, $_SERVER["DOCUMENT_ROOT"]) ) {
trigger_error('Fatal: '. __FILE__
. ' darf nicht in oder unterhalb von DOCUMENT_ROOT ('
. $_SERVER["DOCUMENT_ROOT"] . ') liegen!', E_USER_ERROR);
exit;
}
?>
[#4] plugwash at p10link dot net [2015-03-24 01:38:24]
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.
See http://en.wikipedia.org/wiki/User:Brion_VIBBER/Cool_Cat_incident_report for details of a real world exploit of this.
[#5] answer at question dot forever [2015-03-21 12:14:47]
I'm lazy but rigorous:
<?php
while (list($var,$value) = each ($_SERVER)) {
echo $var." Val:".$value."<br />";
}
<a href="https://blog.sinatranetwork.com/2011/07/20/php-how-to-print-all-_server-variables/">Thank you sir!</a>
?>
[#6] softontherocks at gmail dot com [2014-10-29 18:24:47]
I want to share with you a full function to get the remote IP that calls a PHP url using the $_SERVER array.
function getRealIP(){
?if( $_SERVER['HTTP_X_FORWARDED_FOR'] != '' ){
??$client_ip =
???( !empty($_SERVER['REMOTE_ADDR']) ) ?
????$_SERVER['REMOTE_ADDR']
???:
????????????( ( !empty($_ENV['REMOTE_ADDR']) ) ?
????$_ENV['REMOTE_ADDR']
????:
????"unknown" );
?
??$entries = split('[, ]', $_SERVER['HTTP_X_FORWARDED_FOR']);
?
??reset($entries);
??while (list(, $entry) = each($entries)){
???$entry = trim($entry);
???if ( preg_match("/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/", $entry, $ip_list) ){
????// http://www.faqs.org/rfcs/rfc1918.html
????$private_ip = array(
?????'/^0\./',
?????'/^127\.0\.0\.1/',
?????'/^192\.168\..*/',
?????'/^172\.((1[6-9])|(2[0-9])|(3[0-1]))\..*/',
?????'/^10\..*/');
?
????$found_ip = preg_replace($private_ip, $client_ip, $ip_list[1]);
?
????if ($client_ip != $found_ip){
?????$client_ip = $found_ip;
?????break;
????}
???}
??}
?} else {
??$client_ip =
???( !empty($_SERVER['REMOTE_ADDR']) ) ?
????$_SERVER['REMOTE_ADDR']
???:
????( ( !empty($_ENV['REMOTE_ADDR']) ) ?
????$_ENV['REMOTE_ADDR']
????:
????"unknown" );
?}
?return $client_ip;
}
This function was found in http://softontherocks.blogspot.com/2013/07/obtener-la-direccion-ip-que-solicita.html
[#7] Gary Mathis [2014-10-20 21:40:27]
The best way to see all variables within the $_SERVER array, that I have found, is as follows:
<?php
foreach($_SERVER as $key => $value){
echo '$_SERVER["'.$key.'"] = '.$value."<br />";
}
?>
This will tell you which ones are available on your server and what they are set to.
[#8] Rodolfo Gonzalez Costa Rica [2014-04-04 21:11:18]
This is a short script to know what values are defined
<?php
echo "<textarea>";
print_r($_SERVER);
echo "</textarea>";
?>
[#9] jit_chavan at yahoo dot com [2014-02-13 07:26:53]
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.
[#10] derniereclasse at gmail dot com [2014-01-30 10:44:13]
About $_SERVER['REQUEST_METHOD']
return one of this values :
'GET', 'HEAD', 'POST', 'PUT'.
but can also return :
'OPTION'
[#11] info at salientdigital dot com [2014-01-06 20:46:06]
A word of caution...
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:
<?php
var_dump($_SERVER);
?>
Then from the commandline:
your_account/dir #$ php server.php > your_account_server.txt
your_account/dir #$ sudo php server.php > your_account_sudo_server.txt
your_account/dir #$ sudo bash
root/dir #$ php server.php > root_server.txt
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!
[#12] sendmailz1987 at gmail dot com [2013-11-18 09:13:14]
Example:
$current = $_SERVER['SERVER_NAME'] . $_SERVER['PHP_SELF'];
echo $current;
will output the root to the current page, including url and document root, something like:
example.com/users/profile.php
[#13] @44it [2013-09-25 10:01:53]
All the $_SERVER[''] In php :
<?php
echo "PHP_SELF : " . $_SERVER['PHP_SELF'] . "<br />";
echo "GATEWAY_INTERFACE : " . $_SERVER['GATEWAY_INTERFACE'] . "<br />";
echo "SERVER_ADDR : " . $_SERVER['SERVER_ADDR'] . "<br />";
echo "SERVER_NAME : " . $_SERVER['SERVER_NAME'] . "<br />";
echo "SERVER_SOFTWARE : " . $_SERVER['SERVER_SOFTWARE'] . "<br />";
echo "SERVER_PROTOCOL : " . $_SERVER['SERVER_PROTOCOL'] . "<br />";
echo "REQUEST_METHOD : " . $_SERVER['REQUEST_METHOD'] . "<br />";
echo "REQUEST_TIME : " . $_SERVER['REQUEST_TIME'] . "<br />";
echo "REQUEST_TIME_FLOAT : " . $_SERVER['REQUEST_TIME_FLOAT'] . "<br />";
echo "QUERY_STRING : " . $_SERVER['QUERY_STRING'] . "<br />";
echo "DOCUMENT_ROOT : " . $_SERVER['DOCUMENT_ROOT'] . "<br />";
echo "HTTP_ACCEPT : " . $_SERVER['HTTP_ACCEPT'] . "<br />";
echo "HTTP_ACCEPT_CHARSET : " . $_SERVER['HTTP_ACCEPT_CHARSET'] . "<br />";
echo "HTTP_ACCEPT_ENCODING : " . $_SERVER['HTTP_ACCEPT_ENCODING'] . "<br />";
echo "HTTP_ACCEPT_LANGUAGE : " . $_SERVER['HTTP_ACCEPT_LANGUAGE'] . "<br />";
echo "HTTP_CONNECTION : " . $_SERVER['HTTP_CONNECTION'] . "<br />";
echo "HTTP_HOST : " . $_SERVER['HTTP_HOST'] . "<br />";
echo "HTTP_REFERER : " . $_SERVER['HTTP_REFERER'] . "<br />";
echo "HTTP_USER_AGENT : " . $_SERVER['HTTP_USER_AGENT'] . "<br />";
echo "HTTPS : " . $_SERVER['HTTPS'] . "<br />";
echo "REMOTE_ADDR : " . $_SERVER['REMOTE_ADDR'] . "<br />";
echo "REMOTE_HOST : " . $_SERVER['REMOTE_HOST'] . "<br />";
echo "REMOTE_PORT : " . $_SERVER['REMOTE_PORT'] . "<br />";
echo "REMOTE_USER : " . $_SERVER['REMOTE_USER'] . "<br />";
echo "REDIRECT_REMOTE_USER : " . $_SERVER['REDIRECT_REMOTE_USER'] . "<br />";
echo "SCRIPT_FILENAME : " . $_SERVER['SCRIPT_FILENAME'] . "<br />";
echo "SERVER_ADMIN : " . $_SERVER['SERVER_ADMIN'] . "<br />";
echo "SERVER_PORT : " . $_SERVER['SERVER_PORT'] . "<br />";
echo "SERVER_SIGNATURE : " . $_SERVER['SERVER_SIGNATURE'] . "<br />";
echo "PATH_TRANSLATED : " . $_SERVER['PATH_TRANSLATED'] . "<br />";
echo "SCRIPT_NAME : " . $_SERVER['SCRIPT_NAME'] . "<br />";
echo "REQUEST_URI : " . $_SERVER['REQUEST_URI'] . "<br />";
echo "PHP_AUTH_DIGEST : " . $_SERVER['PHP_AUTH_DIGEST'] . "<br />";
echo "PHP_AUTH_USER : " . $_SERVER['PHP_AUTH_USER'] . "<br />";
echo "PHP_AUTH_PW : " . $_SERVER['PHP_AUTH_PW'] . "<br />";
echo "AUTH_TYPE : " . $_SERVER['AUTH_TYPE'] . "<br />";
echo "PATH_INFO : " . $_SERVER['PATH_INFO'] . "<br />";
echo "ORIG_PATH_INFO : " . $_SERVER['ORIG_PATH_INFO'] . "<br />";
?>
By : @44it
[EDITOR'S NOTE: Removed external link. EDITED BY: thiago]
[#14] wyattstorch42 at outlook dot com [2013-07-13 18:18:05]
<?php
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 versions
return substr($dir, strlen($_SERVER['DOCUMENT_ROOT']));
// Clip off the part of the path outside of the document root
}
require '../classes/Form.php';
new Form()->drawCaptchaField();
// Writes: <img src="/classes/Form.php?captcha" />
if (isset($_GET['captcha'])) {
// generate/return CAPTCHA image
}
class Form {
// ...
public function drawCaptchaField () {
echo '<img src="'.relativeURL().'?captcha" />';
}
}
?>
[#15] pomat at live dot it [2013-06-15 14:12:08]
$_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:
<?php
include(dirname($_SERVER['DOCUMENT_ROOT']) . DIRECTORY_SEPARATOR . 'file.php');
?>
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:
<?php
$path = 'subdir/file.php';
$result = $_SERVER['DOCUMENT_ROOT'] . '/' . $path;
?>
On linux $result might be something like
1) "/var/www/subdir/file.php"
2) "/var/www//subdir/file.php"
String 2 is parsed the same as string 1 (have a try with command 'cd').
On windows $result might be something like
1) "C:/apache/htdocs/subdir/file.php"
2) "C:/apache/htdocs//subdir/file.php"
3) "C:\apache\htdocs/subdir/file.php"
4) "C:\apache\htdocs\/subdir/file.php"
All those strings are parsed as "C:\apache\htdocs\subdir\file.php" (have a try with 'cd').
[#16] sabas88 at gmail dot com [2013-04-10 10:46:54]
I'm the author of this note
http://www.php.net/manual/en/reserved.variables.server.php#100881
I optimized since that note the path function, basically added detection of windows slashes and a partial option
Now is released on github
https://github.com/sabas/magicpath
[#17] zeufonlinux at gmail dot com [2013-02-22 14:24:49]
Just a PHP file to put on your local server (as I don't have enough memory)
<?php
$indicesServer = array('PHP_SELF',
'argv',
'argc',
'GATEWAY_INTERFACE',
'SERVER_ADDR',
'SERVER_NAME',
'SERVER_SOFTWARE',
'SERVER_PROTOCOL',
'REQUEST_METHOD',
'REQUEST_TIME',
'REQUEST_TIME_FLOAT',
'QUERY_STRING',
'DOCUMENT_ROOT',
'HTTP_ACCEPT',
'HTTP_ACCEPT_CHARSET',
'HTTP_ACCEPT_ENCODING',
'HTTP_ACCEPT_LANGUAGE',
'HTTP_CONNECTION',
'HTTP_HOST',
'HTTP_REFERER',
'HTTP_USER_AGENT',
'HTTPS',
'REMOTE_ADDR',
'REMOTE_HOST',
'REMOTE_PORT',
'REMOTE_USER',
'REDIRECT_REMOTE_USER',
'SCRIPT_FILENAME',
'SERVER_ADMIN',
'SERVER_PORT',
'SERVER_SIGNATURE',
'PATH_TRANSLATED',
'SCRIPT_NAME',
'REQUEST_URI',
'PHP_AUTH_DIGEST',
'PHP_AUTH_USER',
'PHP_AUTH_PW',
'AUTH_TYPE',
'PATH_INFO',
'ORIG_PATH_INFO') ;
echo '<table cellpadding="10">' ;
foreach ($indicesServer as $arg) {
if (isset($_SERVER[$arg])) {
echo '<tr><td>'.$arg.'</td><td>' . $_SERVER[$arg] . '</td></tr>' ;
}
else {
echo '<tr><td>'.$arg.'</td><td>-</td></tr>' ;
}
}
echo '</table>' ;
*;q=0.8
HTTP_ACCEPT_CHARSET ISO-8859-1,utf-8;q=0.7,*;q=0.3
HTTP_ACCEPT_ENCODING gzip,deflate,sdch
HTTP_ACCEPT_LANGUAGE fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
HTTP_CONNECTION keep-alive
HTTP_HOST localhost
HTTP_REFERER http://localhost/
HTTP_USER_AGENT Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17
HTTPS -
REMOTE_ADDR 127.0.0.1
REMOTE_HOST -
REMOTE_PORT 65037
REMOTE_USER -
REDIRECT_REMOTE_USER -
SCRIPT_FILENAME E:/web/server_indices.php
SERVER_ADMIN myemail@personal.us
SERVER_PORT 80
SERVER_SIGNATURE
PATH_TRANSLATED -
SCRIPT_NAME /server_indices.php
REQUEST_URI /server_indices.php
PHP_AUTH_DIGEST -
PHP_AUTH_USER -
PHP_AUTH_PW -
AUTH_TYPE -
PATH_INFO -
ORIG_PATH_INFO -
*/
?>
[#18] Dean Jenkins [2013-02-15 19:02:53]
To get the name and web path of the current script
<?php
$scriptname=end(explode('/',$_SERVER['PHP_SELF']));
$scriptpath=str_replace($scriptname,'',$_SERVER['PHP_SELF']);
?>
[#19] krinklemail at gmail dot com [2012-12-05 11:39:34]
If requests to your PHP script send a header "Content-Type" or/ "Content-Length" it will, contrary to regular HTTP headers, not appear in $_SERVER as $_SERVER['HTTP_CONTENT_TYPE']. PHP removes these (per CGI/1.1 specification[1]) from the HTTP_ match group.
They are still accessible, but only if the request was a POST request. When it is, it'll be available as:
$_SERVER['CONTENT_LENGTH']
$_SERVER['CONTENT_TYPE']
[1] https://www.ietf.org/rfc/rfc3875
[#20] Tom [2012-09-06 08:28:24]
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.
[#21] dii3g0 [2012-04-17 16:43:35]
Proccess path_info
<?php
function get_path_info()
{
if( ! array_key_exists('PATH_INFO', $_SERVER) )
{
$pos = strpos($_SERVER['REQUEST_URI'], $_SERVER['QUERY_STRING']);
$asd = substr($_SERVER['REQUEST_URI'], 0, $pos - 2);
$asd = substr($asd, strlen($_SERVER['SCRIPT_NAME']) + 1);
return $asd;
}
else
{
return trim($_SERVER['PATH_INFO'], '/');
}
}
[#22] LOL [2012-04-05 13:26:15]
For an hosting that use windows I have used this script to make REQUEST_URI to be correctly setted on IIS
<?php
function 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();
?>
[#23] picov at e-link dot it [2011-10-13 10:59:01]
A simple function to detect if the current page address was rewritten by mod_rewrite:
<?php
public function urlWasRewritten() {
$realScriptName=$_SERVER['SCRIPT_NAME'];
$virtualScriptName=reset(explode("?", $_SERVER['REQUEST_URI']));
return !($realScriptName==$virtualScriptName);
}
?>
[#24] MarkAgius at markagius dot co dot uk [2011-08-31 02:18:51]
You have missed 'REDIRECT_STATUS'
Very useful if you point all your error pages to the same file.
File; .htaccess
# .htaccess file.
ErrorDocument 404 /error-msg.php
ErrorDocument 500 /error-msg.php
ErrorDocument 400 /error-msg.php
ErrorDocument 401 /error-msg.php
ErrorDocument 403 /error-msg.php
# End of file.
File; error-msg.php
<?php
$HttpStatus = $_SERVER["REDIRECT_STATUS"] ;
if($HttpStatus==200) {print "Document has been processed and sent to you.";}
if($HttpStatus==400) {print "Bad HTTP request ";}
if($HttpStatus==401) {print "Unauthorized - Iinvalid password";}
if($HttpStatus==403) {print "Forbidden";}
if($HttpStatus==500) {print "Internal Server Error";}
if($HttpStatus==418) {print "I'm a teapot! - This is a real value, defined in 1998";}
?>
[#25] Josh Fremer [2010-12-20 10:47:58]
HTTPS
Set to a non-empty value if the script was queried through the HTTPS protocol.
Note: Note that when using ISAPI with IIS, the value will be off if the request was not made through the HTTPS protocol.
=-=-=
To clarify this, the value is the string "off", so a specific non-empty value rather than an empty value as in Apache.
[#26] rulerof at gmail dot com [2010-11-17 10:12:58]
I needed to get the full base directory of my script local to my webserver, IIS 7 on Windows 2008.
I ended up using this:
<?php
function GetBasePath() {
return substr($_SERVER['SCRIPT_FILENAME'], 0, strlen($_SERVER['SCRIPT_FILENAME']) - strlen(strrchr($_SERVER['SCRIPT_FILENAME'], "\\")));
}
?>
And it returned C:\inetpub\wwwroot\<applicationfolder> as I had hoped.
[#27] Stefano (info at sarchittu dot org) [2010-11-12 06:07:22]
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 script
So, for istance, I'll place this into my SCRIPT folder, and I'll write SCRIPT word length in $conflen
<?php
$conflen=strlen('SCRIPT');
$B=substr(__FILE__,0,strrpos(__FILE__,'/'));
$A=substr($_SERVER['DOCUMENT_ROOT'], strrpos($_SERVER['DOCUMENT_ROOT'], $_SERVER['PHP_SELF']));
$C=substr($B,strlen($A));
$posconf=strlen($C)-$conflen-1;
$D=substr($C,1,$posconf);
$host='http://'.$_SERVER['SERVER_NAME'].'/'.$D;
?>
$host will finally contain the absolute path.
[#28] Anonymous [2010-11-12 04:22:55]
Use Strict-Transport-Security (STS) to force the use of SSL.
<?php
$use_sts = TRUE;
if ($use_sts && isset($_SERVER['HTTPS']) {
header('Strict-Transport-Security: max-age=500');
} elseif ($use_sts && !isset($_SERVER['HTTPS']) {
header('Status-Code: 301');
header('Location: https://'.$_SERVER["HTTP_HOST"].$_SERVER['REQUEST_URI']);
}
?>
[#29] dtomasiewicz at gmail dot com [2010-08-14 20:03:47]
To get an associative array of HTTP request headers formatted similarly to get_headers(), this will do the trick:
<?php
function get_request_headers() {
$headers = array();
foreach($_SERVER as $key => $value) {
if(strpos($key, 'HTTP_') === 0) {
$headers[str_replace(' ', '-', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))))] = $value;
}
}
return $headers;
}
?>
[#30] wbeaumo1 at gmail dot com [2010-06-13 20:43:34]
Don't forget $_SERVER['HTTP_COOKIE']. It contains the raw value of the 'Cookie' header sent by the user agent.
[#31] kamazee at gmail dot com [2010-04-15 06:41:04]
$_SERVER['DOCUMENT_ROOT'] in different environments may has trailing slash or not, so be careful when including files from $_SERVER['DOCUMENT_ROOT']:
<?php
include(dirname($_SERVER['DOCUMENT_ROOT']) . DIRECTORY_SEPARATOR . 'file.php')
?>
[#32] php at isnoop dot net [2010-04-01 09:38:32]
Use the apache SetEnv directive to set arbitrary $_SERVER variables in your vhost or apache config.
SetEnv varname "variable value"
[#33] Megan Mickelson [2010-02-22 15:36:55]
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.
htmlspecialchars($_SERVER['REQUEST_URI']);
e.g.
http://www.example.com/foo?<script>...
becomes
http://www.example.com/foo?<script>...
[#34] admin at NOSpAM dot sinfocol dot org [2010-01-14 22:31:46]
I was testing with the $_SERVER variable and some request method, and I found that with apache I can put an arbitrary method.
For example, I have an script called "server.php" in my example webpage with the next code:
<?php
echo $_SERVER['REQUEST_METHOD'];
?>
And I made this request:
c:\>nc -vv www.example.com 80
example.com [x.x.x.x] 80 (http) open
ArbitratyMethod /server.php HTTP/1.1
Host: wow.sinfocol.org
Connection: Close
The response of the server is the next:
HTTP/1.1 200 OK
Date: Fri, 15 Jan 2010 05:14:09 GMT
Server: Apache
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html
ArbitratyMethod
So, be carefully when include the $_SERVER['REQUEST_METHOD'] in any script, this kind of "bug" is old and could be dangerous.
[#35] mirko dot steiner at slashdevslashnull dot de [2009-10-24 02:43:46]
<?php
// RFC 2616 compatible Accept Language Parser
// http://www.ietf.org/rfc/rfc2616.txt, 14.4 Accept-Language, Page 104
// Hypertext Transfer Protocol -- HTTP/1.1
foreach (explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']) as $lang) {
$pattern = '/^(?P<primarytag>[a-zA-Z]{2,8})'.
'(?:-(?P<subtag>[a-zA-Z]{2,8}))?(?:(?:;q=)'.
'(?P<quantifier>\d\.\d))?$/';
$splits = array();
printf("Lang:,,%s''\n", $lang);
if (preg_match($pattern, $lang, $splits)) {
print_r($splits);
} else {
echo "\nno match\n";
}
}
?>
example output:
Google Chrome 3.0.195.27 Windows xp
Lang:,,de-DE''
Array
(
[0] => de-DE
[primarytag] => de
[1] => de
[subtag] => DE
[2] => DE
)
Lang:,,de;q=0.8''
Array
(
[0] => de;q=0.8
[primarytag] => de
[1] => de
[subtag] =>
[2] =>
[quantifier] => 0.8
[3] => 0.8
)
Lang:,,en-US;q=0.6''
Array
(
[0] => en-US;q=0.6
[primarytag] => en
[1] => en
[subtag] => US
[2] => US
[quantifier] => 0.6
[3] => 0.6
)
Lang:,,en;q=0.4''
Array
(
[0] => en;q=0.4
[primarytag] => en
[1] => en
[subtag] =>
[2] =>
[quantifier] => 0.4
[3] => 0.4
)
[#36] Lord Mac [2009-10-14 19:56:59]
An even *more* improved version...
<?php
phpinfo(32);
?>
[#37] steve at sc-fa dot com [2009-09-17 12:20:49]
If you are serving from behind a proxy server, you will almost certainly save time by looking at what these $_SERVER variables do on your machine behind the proxy.
$_SERVER['HTTP_X_FORWARDED_FOR'] in place of $_SERVER['REMOTE_ADDR']
$_SERVER['HTTP_X_FORWARDED_HOST'] and
$_SERVER['HTTP_X_FORWARDED_SERVER'] in place of (at least in our case,) $_SERVER['SERVER_NAME']
[#38] cupy at email dot cz [2009-08-20 08:24:32]
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)
try this example:
------------->8------------------
cat ./script_name.php
#! /usr/bin/php
if( $_SERVER['argc'] == 2)
{
// funny... we have to do this trick to pass e.g. 0x020B from parameters
// ignore this: "PHP Notice: Undefined offset: 2 in ..."
$EID = $_SERVER['argv'][1] + $_SERVER['argv'][2] + $_SERVER['argv'][3];
}
else
{ // default
$EID = 0x0210; // PPS failure
}
[#39] jarrod at squarecrow dot com [2009-08-10 20:31:21]
$_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:
<?php
//Defines constants to use for "include" URLS - helps keep our paths clean
define("REGISTRY_CLASSES", $_SERVER['DOCUMENT_ROOT']."/SOAP/classes/");
define("REGISTRY_CONTROLS", $_SERVER['DOCUMENT_ROOT']."/SOAP/controls/");
define("STRING_BUILDER", REGISTRY_CLASSES. "stringbuilder.php");
define("SESSION_MANAGER", REGISTRY_CLASSES. "sessionmanager.php");
define("STANDARD_CONTROLS", REGISTRY_CONTROLS."standardcontrols.php");
?>
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).
[#40] Richard York [2009-07-09 11:19:14]
Not documented here is the fact that $_SERVER is populated with some pretty useful information when accessing PHP via the shell.
["_SERVER"]=>
array(24) {
["MANPATH"]=>
string(48) "/usr/share/man:/usr/local/share/man:/usr/X11/man"
["TERM"]=>
string(11) "xterm-color"
["SHELL"]=>
string(9) "/bin/bash"
["SSH_CLIENT"]=>
string(20) "127.0.0.1 41242 22"
["OLDPWD"]=>
string(60) "/Library/WebServer/Domains/www.example.com/private"
["SSH_TTY"]=>
string(12) "/dev/ttys000"
["USER"]=>
string(5) "username"
["MAIL"]=>
string(15) "/var/mail/username"
["PATH"]=>
string(57) "/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin"
["PWD"]=>
string(56) "/Library/WebServer/Domains/www.example.com/www"
["SHLVL"]=>
string(1) "1"
["HOME"]=>
string(12) "/Users/username"
["LOGNAME"]=>
string(5) "username"
["SSH_CONNECTION"]=>
string(31) "127.0.0.1 41242 10.0.0.1 22"
["_"]=>
string(12) "/usr/bin/php"
["__CF_USER_TEXT_ENCODING"]=>
string(9) "0x1F5:0:0"
["PHP_SELF"]=>
string(10) "Shell.php"
["SCRIPT_NAME"]=>
string(10) "Shell.php"
["SCRIPT_FILENAME"]=>
string(10) "Shell.php"
["PATH_TRANSLATED"]=>
string(10) "Shell.php"
["DOCUMENT_ROOT"]=>
string(0) ""
["REQUEST_TIME"]=>
int(1247162183)
["argv"]=>
array(1) {
[0]=>
string(10) "Shell.php"
}
["argc"]=>
int(1)
}
[#41] chris [2009-07-02 16:01:16]
A table of everything in the $_SERVER array can be found near the bottom of the output of phpinfo();
[#42] pudding06 at gmail dot com [2009-05-02 14:44:20]
Here's a simple, quick but effective way to block unwanted external visitors to your local server:
<?php
// only local requests
if ($_SERVER['REMOTE_ADDR'] !== '127.0.0.1') die(header("Location: /"));
?>
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.
[#43] dragon[dot]dionysius[at]gmail[dot]com [2009-04-29 10:53:50]
I've updated the function of my previous poster and putted it into my class.
<?php
private function _checkClientLanguage()
{
$langcode = (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : '';
$langcode = (!empty($langcode)) ? explode(";", $langcode) : $langcode;
$langcode = (!empty($langcode['0'])) ? explode(",", $langcode['0']) : $langcode;
$langcode = (!empty($langcode['0'])) ? explode("-", $langcode['0']) : $langcode;
return $langcode['0'];
}
?>
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.
<?php
// if result isn't one of my defined languages
if(!in_array($lang, $language_list)) {
$lang = $language_default; // load default
?>
My HTTP_ACCEPT_LANGUAGE string:
FF3: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
IE7: de-ch
So, take care of it!
[#44] Vladimir Kornea [2009-03-13 17:06:00]
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:
<a href='http://www.example.com/login.php/"><script type="text/javascript">...</script><span a="'>Example.com</a>
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.
[#45] info at mtprod dot com [2009-01-23 02:13:30]
On Windows IIS 7 you must use $_SERVER['LOCAL_ADDR'] rather than $_SERVER['SERVER_ADDR'] to get the server's IP address.
[#46] jonbarnett at gmail dot com [2008-11-23 21:13:20]
It's worth noting that $_SERVER variables get created for any HTTP request headers, including those you might invent:
If the browser sends an HTTP request header of:
X-Debug-Custom: some string
Then:
<?php
$_SERVER['HTTP_X_DEBUG_CUSTOM']; // "some string"
?>
There are better ways to identify the HTTP request headers sent by the browser, but this is convenient if you know what to expect from, for example, an AJAX script with custom headers.
Works in PHP5 on Apache with mod_php. Don't know if this is true from other environments.
[#47] jette at nerdgirl dot dk [2008-11-01 11:43:08]
Windows running IIS v6 does not include $_SERVER['SERVER_ADDR']
If you need to get the IP addresse, use this instead:
<?php
$ipAddress = gethostbyname($_SERVER['SERVER_NAME']);
?>
[#48] geoffrey dot hoffman at gmail dot com [2008-10-25 17:13:53]
If you are looking at $_SERVER['HTTP_USER_AGENT'] to determine whether your user is on a mobile device, you may want to visit these resources:
http://wurfl.sourceforge.net/
http://www.zytrax.com/tech/web/mobile_ids.html
[#49] Thomas Urban [2008-10-22 01:19:51]
Maybe you're missing information on $_SERVER['CONTENT_TYPE'] or $_SERVER['CONTENT_LENGTH'] as I did. On POST-requests these are available in addition to those listed above.
[#50] Taomyn [2008-10-12 07:21:19]
'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.
Does the same for IIS7 running PHP as a Fast-CGI application.
[#51] Tonin [2008-09-16 10:43:38]
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.
[#52] Andrew B [2008-09-08 16:26:06]
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".
[#53] jeff at example dot com [2008-08-12 11:24:04]
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:
SSLOptions +StdEnvVars +ExportCertData
[#54] silverquick at gmail dot com [2008-08-05 17:55:40]
I think the HTTPS element will only be present under Apache 2.x. It's not in the list of "special" variables here:
http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html#RewriteCond
But it is here:
http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#rewritecond
[#55] emailfire at gmail dot com [2008-05-26 07:49:04]
REQUEST_URI is useful, but if you want to get just the file name use:
<?php
$this_page = basename($_SERVER['REQUEST_URI']);
if (strpos($this_page, "?") !== false) $this_page = reset(explode("?", $this_page));
?>