header()函数是在PHP中经常使用的一个函数,但是它具体的作用有用法是什么样的呢,在这两天偶然想到这个问题,将PHP的官网手册以及网络资料作了个总结。
作用 : 发送原生HTTP头。
HTTP协议会有请求头和响应头,说白了header函数会发送一些响应头来通知浏览器。
语法 :
header(string,replace,http_response_code)
参数 | 含义 |
---|---|
string | 必需。规定要发送的报头字符串。 |
replace | 可选。指示该报头是否替换之前的报头,或添加第二个报头。默认是 true(替换)。false(允许相同类型的多个报头)。 |
http_response_code | 可选。把 HTTP 响应代码强制为指定的值。(PHP 4 以及更高版本可用) |
1.首先,在header之前不能有任何输出,因为header是向客气端发送原始的HTTP报头;
由于HTTP协议规定,回应头应该先于回应主体发送,如果有输出主体,则自动设置回应头发送至客气端,所以header就不能再去设置一个已发送的报头;
类似的函数还有 session_start() SetCookie() 等。
2.参数一的string头字符串有两种特别的头;
第一种是以”HTTP/”开头的,将会被用来计算出将要发送的HTTP状态码;
例如在 Apache 服务器上用 PHP 脚本来处理不存在文件的请求(使用 ErrorDocument 指令), 就会希望脚本响应了正确的状态码。
<?php
header("HTTP/1.0 404 Not Found");
?>
第二种是特殊情况是”Location:”的头信息,它不仅把报文发送给浏览器,并且还将返回一个REDIRECT(302)的状态码,除非状态码已经被设置为了201或者3xx。
3.replace
可选参数 replace 表明是否用后面的头替换前面相同类型的头,默认情况下会替换。如果传入 FALSE,就可以强制使相同的头信息并存。
例如:
<?php
header('WWW-Authenticate: Negotiate');
header('WWW-Authenticate: NTLM', false);
?>
4.http_response_code
强制指定HTTP响应的值。注意,这个参数只有在报文字符串(string)不为空的情况下才有效。
5.示例1
保存一个生成的PDF文件。可以使用 Content-Disposition的报文信息来提供一个推荐的文件名,并且强制浏览器显示一个文件下载的对话框。
<?php
// 输出一个PDF文件
header('Content-type: application/pdf');
// 命名为downloaded.pdf
header('Content-Disposition: attachment;filename="downloaded.pdf"');
// 强制浏览器弹出下载对话框
readfile('original.pdf');
?>
6.示例2
PHP脚本总是会生成一些动态内容,而这些内容是不应该被缓存的,不管是客户端浏览器还是在服务器端和客户端浏览器之间的任何代理。可以像这样来强制设置浏览器和各个代理层不缓存数据:
<?php
// HTTP/1.1
header("Cache-Control: no-cache, must-revalidate");
// Date in the past
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
?>
7.由于header函数是向客气端发送回应头的,所以下面的代码是一些回应头的状态。
<?php
header('HTTP/1.1 200 OK'); // ok 正常访问
header('HTTP/1.1 404 Not Found'); // 通知浏览器,页面不存在
header('HTTP/1.1 301 Moved Permanently'); // 设置地址被永久的重定向 301
header('Location: http://www.ithhc.cn/'); // 跳转到一个新的地址
header('Refresh: 10; url=http://www.ithhc.cn/'); // 延迟转向 也就是隔几秒跳转
header('X-Powered-By: PHP/6.0.0'); // 修改 X-Powered-By信息
header('Content-language: en'); // 文档语言
header('Content-Length: 1234'); // 设置内容长度
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $time).' GMT'); // 告诉浏览器最后一次修改时间
header('HTTP/1.1 304 Not Modified'); // 告诉浏览器文档内容没有发生改变
###内容类型###
header('Content-Type: text/html; charset=utf-8'); // 网页编码
header('Content-Type: text/plain'); // 纯文本格式
header('Content-Type: image/jpeg'); // JPG、JPEG
header('Content-Type: application/zip'); // ZIP文件
header('Content-Type: application/pdf'); // PDF文件
header('Content-Type: audio/mpeg'); // 音频文件
header('Content-type: text/css'); //css文件
header('Content-type: text/javascript'); // js文件
header('Content-type: application/json'); // json
header('Content-type: application/pdf'); // pdf
header('Content-type: text/xml'); // xml
header('Content-Type: application/x-shockw**e-flash'); // Flash动画
######
###声明一个下载的文件###
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="ITblog.zip"');
header('Content-Transfer-Encoding: binary');
readfile('test.zip');
######
###对当前文档禁用缓存###
header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
######
###显示一个需要验证的登陆对话框###
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Basic realm="Top Secret"');
######
###声明一个需要下载的xls文件###
header('Content-Disposition: attachment; filename=ithhc.xlsx');
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Length: '.filesize('./test.xls'));
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate');
header('Pragma: public');
readfile('./test.xls');
######
?>
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:
如果安全模式(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的值来实现。
ps:代码部分转载自 http://www.cnblogs.com/huyihao/p/6004800.html
ps:实例与提示部分转载自PHP官方手册
ps:下面这篇文章详细讲解了请求头和响应头的内容
http://blog.youkuaiyun.com/mm2223/article/details/8089645/