# header

(PHP 4, PHP 5, PHP 7)

header — 发送原生 HTTP 头

### 说明

header ( string `$string` [, bool `$replace` = true [, int `$http_response_code` ]] ) : void

header() 用于发送原生的 HTTP 头。关于 HTTP 头的更多信息请参考 » HTTP/1.1 specification。

请注意 header() 必须在任何实际输出之前调用，不管是普通的 HTML 标签，还是文件或 PHP 输出的空行，空格。这是个常见的错误，在通过include，require，或者其访问其他文件里面的函数的时候，如果在header()被调用之前，其中有空格或者空行。 同样的问题也存在于单独的 PHP/HTML 文件中。

    <html>
    <?php
    /* This will give an error. Note the output
     * above, which is before the header() call */
    header('Location: http://www.example.com/');
    exit;
    ?>

### 参数

`string`

  头字符串。

  有两种特别的头。第一种以“HTTP/”开头的 (case is not significant)，将会被用来计算出将要发送的HTTP状态码。 例如在 Apache 服务器上用 PHP 脚本来处理不存在文件的请求（使用 ErrorDocument 指令）， 就会希望脚本响应了正确的状态码。

      <?php
      header("HTTP/1.0 404 Not Found");
      ?>

  第二种特殊情况是“Location:”的头信息。它不仅把报文发送给浏览器，而且还将返回给浏览器一个 REDIRECT（302）的状态码，除非状态码已经事先被设置为了201或者3xx。

      <?php
      header("Location: http://www.example.com/"); /* Redirect browser */

      /* Make sure that code below does not get executed when we redirect. */
      exit;
      ?>

`replace`

  可选参数 `replace` 表明是否用后面的头替换前面相同类型的头。 默认情况下会替换。如果传入 `FALSE`，就可以强制使相同的头信息并存。例如：

      <?php
      header('WWW-Authenticate: Negotiate');
      header('WWW-Authenticate: NTLM', false);
      ?>

`http_response_code`

  强制指定HTTP响应的值。注意，这个参数只有在报文字符串（`string`）不为空的情况下才有效。

### 返回值

没有返回值。

### 更新日志

版本 | 说明
--- | ---
5.1.2 | 这个函数现在可以一次性阻止多个报文信息的发送，从而作为对报文信息注入攻击的一种防护。

### 范例

Example #1 下载对话框

如果你想提醒用户去保存你发送的数据，例如保存一个生成的PDF文件。你可以使用» Content-Disposition的报文信息来提供一个推荐的文件名，并且强制浏览器显示一个文件下载的对话框。

    <?php
    // We'll be outputting a PDF
    header('Content-type: application/pdf');

    // It will be called downloaded.pdf
    header('Content-Disposition: attachment; filename="downloaded.pdf"');

    // The PDF source is in original.pdf
    readfile('original.pdf');
    ?>

Example #2 缓存指令

PHP脚本总是会生成一些动态内容，而这些内容是不应该被缓存的，不管是客户端浏览器还是在服务器端和客户端浏览器之间的任何代理。我们可以像这样来强制设置浏览器和各个代理层不缓存数据：

    <?php
    header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
    header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
    ?>

> Note:

> 也许你会遇到这样的情况，那就是即使你没使用上面这段代码，你的页面也没有被缓存。大多数情况是因为用户可以自己设置他们的浏览器从而改变浏览器默认的缓存行为。一旦发送了上面这段报文信息，那么你就应该重写那些可能用到缓存了的代码。

> 此外，在启用session的情况下，session_cache_limiter()和session.cache_limiter的配置可以用来自动地生成正确的缓存相关的头信息。

### 注释

> Note:

> 数据头只会在SAPI支持时得到处理和输出。

> Note:

> 你所有需要输出到浏览器的数据将会一直缓存在服务器端，直到你发送他们，这将造成比较大的资源开销。你可以是用输出缓冲来避开这个问题。你可以通过在脚本里使用ob_start()和ob_end_flush()或者直接在你的php.ini文件里设置output_buffering，也可以直接在服务器的配置文件里设置。

> Note:

> HTTP状态信息的报文永远都是最新被发送到客户端的，而不管header()是否是在最先发送的。报文状态码可能会被重写，当调用header()来设定新的状态码，除非HTTP报文已经被发送了。

> Note:

> 在IE 4.01和IE 5.5里有bug，要解决就升级浏览器吧，想必也没人用那么远古的神器了吧。

> Note: 如果安全模式（safe mode）被激活，那么脚本的uid将会被添加到WWW-Authenticate的realm部分，前提是你设置了这个头信息的情况下（使用 HTTP 认证）。

> Note:

> HTTP/1.1需要一个绝对的网络资源地址（URI）来作为一个参数供» Location:使用，在其中必须包含了协议，主机地址还有完整的路径，但是一些客户端可以接受相对的网络资源地址。你可以在一个相对的网路资源地址的基础上使用$_SERVER['HTTP_HOST']，$_SERVER['PHP_SELF']和dirname()来组装一个绝对的网路资源地址。

>     <?php
>     /* Redirect to a different page in the current directory that was requested */
>     $host  = $_SERVER['HTTP_HOST'];
>     $uri   = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
>     $extra = 'mypage.php';
>     header("Location: http://$host$uri/$extra");
>     exit;
>     ?>

> Note:

> 在执行Location header跳转的时候，Session ID无法通传递的，即使session.use_trans_sid是激活状态的。只能通过手动传递using `SID`的值来实现。

### 参见

- headers_sent() - 检测 HTTP 头是否已经发送
- setcookie() - 发送 Cookie
- http_response_code() - 获取/设置响应的 HTTP 状态码
- The section on HTTP authentication