• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • $_SERVER

    $HTTP_SERVER_VARS[已删除]

    服务器和执行环境信息

    说明

    $_SERVER是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。这个数组中的项目由 Web 服务器创建。不能保证每个服务器都提供全部项目;服务器可能会忽略一些,或者提供一些没有在这里列举出来的项目。这也就意味着大量的此类变量都会在» CGI 1.1 规范中说明,所以应该仔细研究一下。

    Note: PHP 5.4.0 之前,$HTTP_SERVER_VARS包含着相同的信息,但它不是一个超全局变量。(注意$HTTP_SERVER_VARS$_SERVER是不同的变量,PHP处理它们的方式不同)

    目录

    $_SERVER中,你也许能够,也许不能够找到下面的这些元素。注意,如果以命令行方式运行 PHP,下面列出的元素几乎没有有效的(或是没有任何实际意义的)。

    'PHP_SELF'
    当前执行脚本的文件名,与 document root 有关。例如,在地址为http://example.com/foo/bar.php的脚本中使用$_SERVER['PHP_SELF']将得到/foo/bar.php。__FILE__常量包含当前(例如包含)文件的完整路径和文件名。从 PHP 4.3.0 版本开始,如果 PHP 以命令行模式运行,这个变量将包含脚本名。之前的版本该变量不可用。
    'argv'
    传递给该脚本的参数的数组。当脚本以命令行方式运行时,argv 变量传递给程序 C 语言样式的命令行参数。当通过 GET 方式调用时,该变量包含query string。
    'argc'
    包含命令行模式下传递给该脚本的参数的数目(如果运行在命令行模式下)。
    'GATEWAY_INTERFACE'
    服务器使用的 CGI 规范的版本;例如,“CGI/1.1”。
    'SERVER_ADDR'
    当前运行脚本所在的服务器的 IP 地址。
    'SERVER_NAME'
    当前运行脚本所在的服务器的主机名。如果脚本运行于虚拟主机中,该名称是由那个虚拟主机所设置的值决定。

    Note:在 Apache 2 里,必须设置UseCanonicalName = OnServerName。否则该值会由客户端提供,就有可能被伪造。上下文有安全性要求的环境里,不应该依赖此值。

    'SERVER_SOFTWARE'
    服务器标识字符串,在响应请求时的头信息中给出。
    'SERVER_PROTOCOL'
    请求页面时通信协议的名称和版本。例如,“HTTP/1.0”。
    'REQUEST_METHOD'
    访问页面使用的请求方法;例如,“GET”,“HEAD”,“POST”,“PUT”。

    Note:

    如果请求方法为HEAD,PHP 脚本将在发送 Header 头信息之后终止(这意味着在产生任何输出后,不再有输出缓冲)。

    'REQUEST_TIME'
    请求开始时的时间戳。从 PHP 5.1.0 起可用。
    'REQUEST_TIME_FLOAT'
    请求开始时的时间戳,微秒级别的精准度。自 PHP 5.4.0 开始生效。
    'QUERY_STRING'
    query string(查询字符串),如果有的话,通过它进行页面访问。
    'DOCUMENT_ROOT'
    当前运行脚本所在的文档根目录。在服务器配置文件中定义。
    'HTTP_ACCEPT'
    当前请求头中Accept:项的内容,如果存在的话。
    'HTTP_ACCEPT_CHARSET'
    当前请求头中Accept-Charset:项的内容,如果存在的话。例如:“iso-8859-1,*,utf-8”。
    'HTTP_ACCEPT_ENCODING'
    当前请求头中Accept-Encoding:项的内容,如果存在的话。例如:“gzip”。
    'HTTP_ACCEPT_LANGUAGE'
    当前请求头中Accept-Language:项的内容,如果存在的话。例如:“en”。
    'HTTP_CONNECTION'
    当前请求头中Connection:项的内容,如果存在的话。例如:“Keep-Alive”。
    'HTTP_HOST'
    当前请求头中Host:项的内容,如果存在的话。
    'HTTP_REFERER'
    引导用户代理到当前页的前一页的地址(如果存在)。由 user agent 设置决定。并不是所有的用户代理都会设置该项,有的还提供了修改HTTP_REFERER的功能。简言之,该值并不可信。
    'HTTP_USER_AGENT'
    当前请求头中User-Agent:项的内容,如果存在的话。该字符串表明了访问该页面的用户代理的信息。一个典型的例子是:Mozilla/4.5[en](X11; U; Linux 2.2.9 i586)。除此之外,你可以通过get_browser()来使用该值,从而定制页面输出以便适应用户代理的性能。
    'HTTPS'
    如果脚本是通过 HTTPS 协议被访问,则被设为一个非空的值。
    Note:注意当使用 IIS 上的 ISAPI 方式时,如果不是通过 HTTPS 协议被访问,这个值将为off

    'REMOTE_ADDR'
    浏览当前页面的用户的 IP 地址。
    'REMOTE_HOST'
    浏览当前页面的用户的主机名。DNS 反向解析不依赖于用户的REMOTE_ADDR

    Note:你的服务器必须被配置以便产生这个变量。例如在 Apache 中,你需要在httpd.conf中设置HostnameLookups On来产生它。参见gethostbyaddr()。

    'REMOTE_PORT'
    用户机器上连接到 Web 服务器所使用的端口号。
    'REMOTE_USER'
    经验证的用户
    'REDIRECT_REMOTE_USER'
    验证的用户,如果请求已在内部重定向。
    'SCRIPT_FILENAME'

    当前执行脚本的绝对路径。

    Note:

    如果在命令行界面(Command Line Interface, CLI)使用相对路径执行脚本,例如file.php../file.php,那么$_SERVER['SCRIPT_FILENAME']将包含用户指定的相对路径。

    'SERVER_ADMIN'
    该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。如果脚本运行在一个虚拟主机上,则该值是那个虚拟主机的值。
    'SERVER_PORT'
    Web 服务器使用的端口。默认值为“80”。如果使用 SSL 安全连接,则这个值为用户设置的 HTTP 端口。
    Note:在 Apache 2 里,为了获取真实物理端口,必须设置UseCanonicalName = On以及UseCanonicalPhysicalPort = On。否则此值可能被伪造,不一定会返回真实端口值。上下文有安全性要求的环境里,不应该依赖此值。

    'SERVER_SIGNATURE'
    包含了服务器版本和虚拟主机名的字符串。
    'PATH_TRANSLATED'
    当前脚本所在文件系统(非文档根目录)的基本路径。这是在服务器进行虚拟到真实路径的映像后的结果。

    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

    'SCRIPT_NAME'
    包含当前脚本的路径。这在页面需要指向自己时非常有用。__FILE__常量包含当前脚本(例如包含文件)的完整路径和文件名。
    'REQUEST_URI'
    URI 用来指定要访问的页面。例如“/index.html”。
    'PHP_AUTH_DIGEST'
    当作为 Apache 模块运行时,进行 HTTP Digest 认证的过程中,此变量被设置成客户端发送的“Authorization” HTTP 头内容(以便作进一步的认证操作)。
    'PHP_AUTH_USER'
    当 PHP 运行在 Apache 或 IIS(PHP 5 是 ISAPI)模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的用户名。
    'PHP_AUTH_PW'
    当 PHP 运行在 Apache 或 IIS(PHP 5 是 ISAPI)模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的密码。
    'AUTH_TYPE'
    当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是认证的类型。
    'PATH_INFO'
    包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息,如果存在的话。例如,如果当前脚本是通过 URLhttp://www.example.com/php/path_info.php/some/stuff?foo=bar被访问,那么$_SERVER['PATH_INFO']将包含/some/stuff
    'ORIG_PATH_INFO'
    在被 PHP 处理之前,“PATH_INFO”的原始版本。

    更新日志

    版本说明
    5.4.0因为移除了 long array register 功能,$HTTP_SERVER_VARS不再有效。
    5.3.0废弃了使$HTTP_SERVER_VARS生效的register_long_arrays指令。
    4.1.0引入$_SERVER,弃用$HTTP_SERVER_VARS

    范例

    Example #1$_SERVER范例

    <?php
    echo $_SERVER['SERVER_NAME'];
    ?>
    

    以上例程的输出类似于:

    www.example.com
    

    注释

    Note:

    “Superglobal”也称为自动化的全局变量。这就表示其在脚本的所有作用域中都是可用的。不需要在函数或方法中用global $variable;来访问它。

    参见

    • 过滤器扩展
    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>' ;
    /*
    That will give you the result of each variable like (if the file is server_indices.php at the root and Apache Web directory is in E:\web) : 
    PHP_SELF  /server_indices.php
    argv  -
    argc  -
    GATEWAY_INTERFACE  CGI/1.1
    SERVER_ADDR  127.0.0.1
    SERVER_NAME  localhost
    SERVER_SOFTWARE  Apache/2.2.22 (Win64) PHP/5.3.13
    SERVER_PROTOCOL  HTTP/1.1
    REQUEST_METHOD  GET
    REQUEST_TIME  1361542579
    REQUEST_TIME_FLOAT  -
    QUERY_STRING  
    DOCUMENT_ROOT  E:/web/
    HTTP_ACCEPT  text/html,application/xhtml+xml,application/xml;q=0.9,*/*;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  -
    */
    ?>
    
    So near, and yet so far …
    $_SERVER has nearly everything you need to know about the current web page environment. Something which would have been handy is easy access to the protocol and the actual web root.
    For the protocol, you may or may not have $_SERVER['HTTPS'] and it may or may not be empty. For the web root, $_SERVER['DOCUMENT_ROOT'] depends on the server configuration, and doesn’t work for virtual hosts.
    For practical purposes, I normally include something like the following in my scripts:
    <?php
      //  Web Root
      //  Usage: include("$root/includes/something.inc.php");
        $root = $_SERVER['WEB_ROOT'] = str_replace($_SERVER['SCRIPT_NAME'],'',$_SERVER['SCRIPT_FILENAME']);
      //  Host & Protocol
      //  Usage: $url = "$protocol://$host/images/something.jpg";
        $host = $_SERVER['HTTP_HOST'];
        $protocol=$_SERVER['PROTOCOL'] = isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) ? 'https' : 'http';
    ?>
    
    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.
    As PHP $_SERVER var is populated with a lot of vars, I think it's important to say that it's also populated with environment vars.
    For example, with a PHP script, we can have this:
      MY_ENV_VAR=Hello php -r 'echo $_SERVER["MY_ENV_VAR"];'
      
    Will show "Hello".
    But, internally, PHP makes sure that "internal" keys in $_SERVER are not overriden, so you wouldn't be able to do something like this:
      REQUEST_TIME=Hello php -r 'var_dump($_SERVER["REQUEST_TIME"]);'
      
    Will show something like 1492897785
    However, a lot of vars are still vulnerable from environment injection.
    I created a gist here ( https://gist.github.com/Pierstoval/f287d3e61252e791a943dd73874ab5ee ) with my PHP configuration on windows with PHP7.0.15 on WSL with bash, the results are that the only "safe" vars are the following:
    PHP_SELF
    SCRIPT_NAME
    SCRIPT_FILENAME
    PATH_TRANSLATED
    DOCUMENT_ROOT
    REQUEST_TIME_FLOAT
    REQUEST_TIME
    argv
    argc
    All the rest can be overriden with environment vars, which is not very cool actually because it can break PHP applications sometimes...
    (and I only tested on CLI, I had no patience to test with Apache mod_php or Nginx + PHP-FPM, but I can imagine that not a lot of $_SERVER properties are "that" secure...)
    A snippet to list the header values:
    <?php
    echo <<<END
    <!DOCTYPE html>
    <meta charset="UTF-8" />
    <title>\$_SERVER</title>
    <style>
      table {
        border-collapse: collapse;
      }
      td {
        border: 1px solid #999;
        padding: 3px;
      }
    </style>
    <table>
    END;
    foreach ($_SERVER as $k => $v) {
      $key = htmlentities($k);
      $value = htmlentities($v);
      echo "\n\t<tr>\n\t\t<td>$key\n\t\t<td>$value\n";
    }
    echo "</table>";
    ?>
    
    An even *more* improved version...
    <?php
    phpinfo(32);
    ?>
    
    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
    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";}
    ?>
    
    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']
    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.
    In 2018 things can be pretty cool !!!
    look around:
    <?php
    //save it index.php in a root folder
    /*
      if($_SERVER["REQUEST_METHOD"]!='GET'){
        echo('it`s a POST');
      }else{  
        echo('it`s a GET');
      }
    */
    $_REQ =& $_SERVER["REQUEST_METHOD"];
    ($_REQ=='POST')and($what='it`s a POST');
    ($_REQ=='GET')and($what='it`s a GET');
    isset($what) and print($what);
    ?>
    <form method="POST" action=""> 
    <input type="text" name="postbaby" value="sadasdsa">
    <input type="submit" value="POST THAT">
    </form>
    <br>
    <form method="GET" action=""> 
    <input type="text" name="getbaby" value="sadasdsa">
    <input type="submit" value="GET THAT">
    </form>
    <hr><?php
    phpinfo();
    ?>
    what if you have a class with controllers?
    i hope will not be depreciated cause STATIC CALLS I TEST ALREADY ARE VERY FAST:
    <?php
    //save it index.php in a root folder
    /*
      if($_SERVER["REQUEST_METHOD"]!='GET'){
        echo('it`s a POST');
      }else{  
        echo('it`s a GET');
      }
    */
    class forms {
      public static function type(){
        return $_SERVER["REQUEST_METHOD"];
      }
      public static function post($f){
        (self::type()=='POST')and $f();
      }
      
      public static function get($f){
        (self::type()=='GET')and $f();
      }
    }
    ?>
    <form method="POST" action=""> 
    <input type="text" name="postbaby" value="sadasdsa">
    <input type="submit" value="POST THAT">
    </form>
    <br>
    <form method="GET" action=""> 
    <input type="text" name="getbaby" value="sadasdsa">
    <input type="submit" value="GET THAT">
    </form>
    <hr><?php
    forms::post(function(){
      $what='it`s a POST';echo($what);
    });
    forms::get(function(){
      $what='it`s a GET';echo($what);
    });
    //phpinfo();
    ?>
    
    If you apply redirection in ALL your requests using commands at the Apache virtual host file like:
    RewriteEngine On
    RewriteCond "%{REQUEST_URI}" "!=/index.php"
    RewriteRule "^/(.*)$" "index.php?$1" [NC,NE,L,QSA]
    you should expect some deviations in your $_SERVER global.
    Say, you send a url of: [hostname here]/a/b?x=1&y=2
    which makes Apache to modify to: /index.php?/a/b?x=1&y=2
    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.
    To test your $_SERVER global:
    function serverArray(){
      $arr = array();
      foreach($_SERVER as $key=>$value)
       $arr[] = '&nbsp;&nbsp;&nbsp;\'' . $key . '\' => \'' . (isset($value)? $value : '-') . '\'';
      return @\sort($arr)? '$_SERVER = array(<br />' . implode($arr, ',<br />') . '<br />);' : false;
    }
    echo serverArray();
    Note that $_SERVER['REQUEST_URI'] might include the scheme and domain in certain cases.
    This happens, for example, when calling the page through a call to stream_context_create() with a HTTP header of 'request_fulluri' set to 1.
    For example:
    $http = ['request_fulluri' => 1, /* other params here */];
    $context = stream_context_create(array( 'http' => $http ));
    $fp = fopen($some_url, 'rb', false, $context);
    When outputting $_SERVER['REQUEST_URI'] on the server at $some_url, you will get
    https://some_url/some_script.php
    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:
    $scheme = $_SERVER['REQUEST_SCHEME'] . '://';
    if (strcmp(substr($_SERVER['REQUEST_URI'], 0, strlen($scheme)), $scheme) === 0) {
      // request_fulluri was set
    }
    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.
    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.
    Guide to absolute paths...
    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['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 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.
    <?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 versions
      return substr($dir, strlen($_SERVER['DOCUMENT_ROOT']));
        // Clip off the part of the path outside of the document root
    }
    /*
     *contact/index.php
     */
    require '../classes/Form.php';
    new Form() >drawCaptchaField();
      // Writes: <img src="/classes/Form.php?captcha" />
      
    /*
     * classes/Form.php
     */
    if (isset($_GET['captcha'])) {
      // generate/return CAPTCHA image
    }
    class Form {
      // ...
      public function drawCaptchaField () {
        echo '<img src="'.relativeURL().'?captcha" />';
      }
    }
    ?>
    
    Use the apache SetEnv directive to set arbitrary $_SERVER variables in your vhost or apache config.
    SetEnv varname "variable value"
    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.
    A table of everything in the $_SERVER array can be found near the bottom of the output of phpinfo();
    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.
    $_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').
    <?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
    )
    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.
    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)
     }
    $_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).
    Guide to URL paths...
    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
    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.
    To get an associative array of HTTP request headers formatted similarly to get_headers(), this will do the trick:
    <?php
    /**
     * Transforms $_SERVER HTTP headers into a nice associative array. For example:
     *  array(
     *    'Referer' => 'example.com',
     *    'X-Requested-With' => 'XMLHttpRequest'
     *  )
     */
    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;
    }
    ?>
    
    Guide to script parameters...
    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
    Don't forget $_SERVER['HTTP_COOKIE']. It contains the raw value of the 'Cookie' header sent by the user agent.
    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.
    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.
    On Windows IIS 7 you must use $_SERVER['LOCAL_ADDR'] rather than $_SERVER['SERVER_ADDR'] to get the server's IP address.
    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']);
    ?>
    
    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
      }
    <?php
    /*
    Sometimes you will find that your website will not get the correct user IP after adding CDN, then this function will help you
    */
    function real_ip()
    {
      $ip = $_SERVER['REMOTE_ADDR'];
      if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
        foreach ($matches[0] AS $xip) {
          if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) {
            $ip = $xip;
            break;
          }
        }
      } elseif (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
      } elseif (isset($_SERVER['HTTP_CF_CONNECTING_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CF_CONNECTING_IP'])) {
        $ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
      } elseif (isset($_SERVER['HTTP_X_REAL_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_X_REAL_IP'])) {
        $ip = $_SERVER['HTTP_X_REAL_IP'];
      }
      return $ip;
    }
    echo real_ip();
    ?>
    
    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);
    }
    ?>
    
    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
    PHP_SELF is a disgrace of a programmer's work. One of the most widespread PHP vulnerabilities since version 4 and the manual says nothing about the dangers. At least clarify that ITS VALUE CAN BE PROVIDED BY THE USER with capitals preferably if you want to make the internet a safer place...
    Remember,
    Although $_SERVER["REQUEST_METHOD"] is initially built with GET, POST, PUT, HEAD in mind, a server can allow more. 
    This may be important if you're building a RESTful interfaces that will also use methods such as PATCH and DELETE.
    Also important as a security risk as a possible point of injection. In the event of building something acting based on REQUEST_METHOD, it's recommended to put it in a switch statement.
    <?php
    switch ($_SERVER["REQUEST_METHOD"]){
      case "PUT":
        foo_replace_data();
        break;
      case "POST":
        foo_add_data();
        break;
      case "HEAD";
        foo_set_that_cookie();
        break;
      case "GET":
      default:
       foo_fetch_stuff()
       break;
    }
    ?>
    

    上篇:$GLOBALS

    下篇:$_GET