1
0
mirror of https://github.com/php/doc-zh.git synced 2026-03-24 15:12:20 +01:00
Files
2024-01-20 08:27:09 +08:00

295 lines
10 KiB
XML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- $Author$ -->
<!-- EN-Revision: 5c1ccc6e24e5d470e75ef0a5887c2ff583266375 Maintainer: zhoumengkang Status: ready -->
<!-- CREDITS: Luffy -->
<refentry xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://docbook.org/ns/docbook" xml:id="function.header">
<refnamediv>
<refname>header</refname>
<refpurpose>发送原生 HTTP 头</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<type>void</type><methodname>header</methodname>
<methodparam><type>string</type><parameter>string</parameter></methodparam>
<methodparam choice="opt"><type>bool</type><parameter>replace</parameter><initializer>true</initializer></methodparam>
<methodparam choice="opt"><type>int</type><parameter>response_code</parameter></methodparam>
</methodsynopsis>
<para>
<function>header</function> 用于发送原生的 <acronym>HTTP</acronym>
头。关于 <acronym>HTTP</acronym> 头的更多信息请参考 <link xlink:href="&url.rfc;2616">HTTP/1.1 specification</link>
</para>
<para>
请注意 <function>header</function> 必须在任何实际输出之前调用,不管是普通的 HTML 标签,还是文件或 PHP 输出的空行,空格。这是个常见的错误,在通过<function>include</function><function>require</function>,或者其访问其他文件里面的函数的时候,如果在<function>header</function>被调用之前,其中有空格或者空行。
同样的问题也存在于单独的 PHP/HTML 文件中。
<informalexample>
<programlisting role="php">
<![CDATA[
<html>
<?php
/* This will give an error. Note the output
* above, which is before the header() call */
header('Location: http://www.example.com/');
exit;
?>
]]>
</programlisting>
</informalexample>
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
<variablelist>
<varlistentry>
<term><parameter>string</parameter></term>
<listitem>
<para>
头字符串。
</para>
<para>
有两种特别的头。第一种以“<literal>HTTP/</literal>”开头的 (case is not
significant)将会被用来计算出将要发送的HTTP状态码。
例如在 Apache 服务器上用 PHP 脚本来处理不存在文件的请求(使用 <literal>ErrorDocument</literal> 指令), 就会希望脚本响应了正确的状态码。
</para>
<para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
// 本示例演示了 "HTTP/" 的特殊例子,典型用法的最佳实践,包括:
// 1. header($_SERVER["SERVER_PROTOCOL"] . " 404 Not Found");
// (覆盖 http 状态消息,兼容还在使用 HTTP/1.0 的客户端)
// 2. http_response_code(404); (使用默认消息)
header("HTTP/1.1 404 Not Found");
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
第二种特殊情况是“Location:”的头信息。它不仅把报文发送给浏览器,而且还将返回给浏览器一个 <literal>REDIRECT</literal>302的状态码除非状态码已经事先被设置为了<literal>201</literal>或者<literal>3xx</literal>
</para>
<para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
header("Location: http://www.example.com/"); /* Redirect browser */
/* Make sure that code below does not get executed when we redirect. */
exit;
?>
]]>
</programlisting>
</informalexample>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>replace</parameter></term>
<listitem>
<para>
可选参数 <parameter>replace</parameter> 表明是否用后面的头替换前面相同类型的头。
默认情况下会替换。如果传入 &false;,就可以强制使相同的头信息并存。例如:
</para>
<para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
header('WWW-Authenticate: Negotiate');
header('WWW-Authenticate: NTLM', false);
?>
]]>
</programlisting>
</informalexample>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>response_code</parameter></term>
<listitem>
<para>
强制指定 HTTP 响应的值。注意,这个参数只有在报文字符串(<parameter>header</parameter>)不为空的情况下才有效。
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
&return.void;
</para>
</refsect1>
<refsect1 role="errors">
&reftitle.errors;
<para>
当 header 发送失败时,<function>header</function> 会抛出 <constant>E_WARNING</constant> 级别的错误
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example>
<title>下载对话框</title>
<para>
如果你想提醒用户去保存你发送的数据例如保存一个生成的PDF文件。你可以使用<link
xlink:href="&url.rfc;2183">Content-Disposition</link>的报文信息来提供一个推荐的文件名,并且强制浏览器显示一个文件下载的对话框。
</para>
<programlisting role="php">
<![CDATA[
<?php
// 输出 PDF 文件
header('Content-type: application/pdf');
// 名称为 downloaded.pdf
header('Content-Disposition: attachment; filename="downloaded.pdf"');
// 该 PDF 来源于 original.pdf
readfile('original.pdf');
?>
]]>
</programlisting>
</example>
</para>
<para>
<example>
<title>缓存指令</title>
<para>
PHP 脚本经常生成一些动态内容,它不该被客户端、服务器与浏览器之间的代理缓存。
许多代理与客户端都支持这样强制禁用缓存:
</para>
<programlisting role="php">
<![CDATA[
<?php
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // 过去的日期
?>
]]>
</programlisting>
<para>
<note>
<para>
也许你会遇到这样的情况,那就是即使你没使用上面这段代码,你的页面也没有被缓存。大多数情况是因为用户可以自己设置他们的浏览器从而改变浏览器默认的缓存行为。一旦发送了上面这段报文信息,那么你就应该重写那些可能用到缓存了的代码。
</para>
<para>
此外在启用session的情况下<function>session_cache_limiter</function><literal>session.cache_limiter</literal>的配置可以用来自动地生成正确的缓存相关的头信息。
</para>
</note>
</para>
</example>
</para>
<para>
<example>
<title>设置一个 Cookie</title>
<para>
<function>setcookie</function> 提供了一个方便的方式来设置 Cookie。
要设置一个包含 <function>setcookie</function> 函数不支持的属性的 Cookie可以使用 <function>header</function>
</para>
<para>
例如,以下代码设置了一个包含 <literal>Partitioned</literal> 属性的 Cookie。
</para>
<programlisting role="php">
<![CDATA[
<?php
header('Set-Cookie: name=value; Secure; Path=/; SameSite=None; Partitioned;');
?>
]]>
</programlisting>
</example>
</para>
</refsect1>
<refsect1 role="notes">
&reftitle.notes;
&note.network.header.sapi;
<note>
<para>
你所有需要输出到浏览器的数据将会一直缓存在服务器端,直到你发送他们,这将造成比较大的资源开销。你可以是用输出缓冲来避开这个问题。你可以通过在脚本里使用<function>ob_start</function><function>ob_end_flush</function>或者直接在你的&php.ini;文件里设置<literal>output_buffering</literal>,也可以直接在服务器的配置文件里设置。
</para>
</note>
<note>
<para>
HTTP状态信息的报文永远都是最新被发送到客户端的而不管<function>header</function>是否是在最先发送的。报文状态码可能会被重写,当调用<function>header</function>来设定新的状态码除非HTTP报文已经被发送了。
</para>
</note>
<note>
<para>
绝大多数现代浏览器的 <link xlink:href="&spec.http1.1;#section-7.1.2">Location:</link>
都支持相对 <acronym>URI</acronym>,但也有一些旧浏览器需要绝对 URI包含协议、主机名、绝对路径。
一般情况下,可以借助 <varname>$_SERVER['HTTP_HOST']</varname><varname>$_SERVER['PHP_SELF']</varname>
<function>dirname</function> 将相对地址组合成绝对 URI
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
/* 根据当前请求所在的目录,重定向到不同的页面 */
$host = $_SERVER['HTTP_HOST'];
$uri = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
$extra = 'mypage.php';
header("Location: http://$host$uri/$extra");
exit;
?>
]]>
</programlisting>
</informalexample>
</para>
</note>
<note>
<para>
在执行Location header跳转的时候Session ID无法通传递的即使<link
linkend="ini.session.use-trans-sid">session.use_trans_sid</link>是激活状态的。只能通过手动传递using <constant>SID</constant>的值来实现。
</para>
</note>
</refsect1>
<refsect1 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><function>headers_sent</function></member>
<member><function>setcookie</function></member>
<member><function>http_response_code</function></member>
<member><function>header_remove</function></member>
<member><function>headers_list</function></member>
<member>
The section on <link linkend="features.http-auth">HTTP
authentication</link>
</member>
</simplelist>
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->