代码改变世界

PHP中的输出控制总结

2011-11-12 11:47  AnyKoro  阅读(433)  评论(0编辑  收藏  举报

Output Control(输出控制)

简介                                                                                                                                                                            

当通过脚本发送输出时,可以使用输出控制函数进行控制。在一些不同的场合很有用,在你的脚本已开始输出数据后,如果你需要发送headers到浏览器,这时会更加有用。输出控制函数不会影响通过header()或setcookie()发送的headers,只会影响像echo(),还有在PHP代码块之间的数据。
正常来说,如果不适用输出缓存,当出现HTML标签,echo时,都是即时向客户端发送的。这样在使用header(),setcookie()等函数时,就容易出现问题。但是,你可以通过使用输出缓存去解决这个问题。因为当启用输出缓存后,你所有发送给浏览器的输出都会在服务器进行缓存直到你通过调用函数去发送这些输出。你可以通过在你的脚本中调用ob_start()和ob_end_flush(),或在php.ini中设置output_buffering配置来实现。 这样就意味着,你可以通过命令来安排优先级进行信息的发送。例子:

<?php
ob_start();
echo "data in outputBuffer";
?>
<html>
<head>
<?php
header("Location:www.baidu.com");
?>
</head>
<body>
test body
</body>
</html>
<?php
ob_end_flush();
?>

这样是不会出错的,否则如果没有ob_start()和ob_end_flush()的话,就会出现错误,就是header()前不能有输出的错误。

运行时配置                                                                                                                                                                  

php.ini中的一些相关配置信息,均会影响输出控制函数的行为。

输出控制配置项
NameDefaultChangeableChangelog
output_buffering "0" PHP_INI_PERDIR  
output_handler NULL PHP_INI_PERDIR Available since PHP 4.0.4.
implicit_flush "0" PHP_INI_ALL

PHP_INI_PERDIR in PHP <= 4.2.3.

更多PHP_INI_*模式的细节可以参看Where a configuration setting may be set.

配置项解释:

output_buffering boolean/integer
    打开时('On'),为所有文件启用输出缓存。如果你希望限定buffer的大小,你可以使用数字代替'On',该数字的单位为字节(byte)。

output_handler string
    将脚本的所有输出重定向到一个函数上。例如,你设置output_handler为mb_output_handler(),那么输出字符将被透明地转换成指定的字符。设置一些输出处理,以自动打开输出缓存。

implicit_flush boolean
    默认为False,如果为True的话,表示PHP会告诉输出层在每次输出块(Block)后,自动冲刷(Flush)。相当于在每次print()、echo()或输出HTML块后调用了flush()函数。
    当在web环境中使用php时,打开此选项会有潜在的性能问题,所以一般推荐在做调试的时候使用。

 

基本使用                                                                                                                                                                  

 

<?php

ob_start();
echo "Hello\n";

setcookie("cookiename", "cookiedata");

ob_end_flush();

?>

在上例中,echo()的输出会被存放在output buffer中,直到ob_end_flush()被调用。期间,setcookie()会成功储存一个cookie,不会引起错误。(一般你不能在数据已经发送后再向浏览器发送头信息(header)。)

输出控制函数                                                                                                                                                          

在讲解这段前,先需要说明下header()和setcookie()函数。

——header()——

作用:发送一个原始的HTTP头信息
语法:void header ( string $string [, bool $replace = true [, int $http_response_code ]] )
说明:header()必须在任何输出被发送前调用。当使用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/');
?>

参数:

string string
      头信息字符串
      这里有两个特例,第一个是以'HTTP/'开头的,它用于指出要发送的HTTP状态码。比如,如果你配置Apache,使用PHP脚本去处理没有找到文件的请求,你就会希望你的脚本会产生正确的状态码。

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

如果说你用FastCGI的话,你就得要用一下形式指明

<?php
header("Status: 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 boolean
      replace参数是可选的,该参数表明,该头信息是否应该替换先前相似的头信息,或添加第二个相同类型的头信息。默认是替换的,当传入False的时候,可以强行设置多个相同类型的头信息。

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

http_response_code integer
      强行将HTTP响应值设定为指定值。注意,只有当string参数不为空时,才有作用。

注意:在php5以后的版本中,禁止同时发送头信息超过一个,这个是为了防止头信息注入攻击。

——setcookie()——
作用:发送一个cookie
语法:bool setcookie ( string $name [, string $value [, int $expire = 0 [, string $path [, string $domain [, bool $secure = false [, bool $httponly = false ]]]]]] )
说明:setcookie()定义了一个cookie,与其余的HTTP头信息一同发送。像其他header一样,cookies必须在你脚本中的任何输出前发送。(这是协议约束)。这需要你将setcookie()调用放在任何输出之前,这些输出包括<html>和<head>标签,甚至任何的空格。一旦设置了cookie,就可以在其他页面使用$_COOKIE、$_REQUEST又或$HTTP_COOKIE_VARS数组访问。 

参数:
name string
cookie的名称

value string
cookie的值。该数值存放在客户电脑中。请不要存放敏感信息。该值可以通过$_COOKIE['cookiename']进行访问。

expire int
cookie的过期时间,这里存放的是时间戳。可以使用time()+过期时间段的描述,或使用mktime()。
time():返回当前Unix时间戳 mktime():获得指定日期的Unix时间戳

path string
cookie只有在指定的服务器路径下才会起作用,使用path指定路径。如果设置成'/',cookie将对整个domain有效。如果设置成'/foo/',cookie只会在domain下的/foo/目录及其子目录有效。默认值为当前设定cookie的目录位置。

domian string
cookie起作用的域名。设置成'.example.com',就表示cookie将对所有example.com及其子域名有效。尽管一些浏览器可以接受不以'.'开始的内容,但是还是应该包括'.'的。比如如果设置domain为'www.example.com'或'.www.example.com'将使得cookie只会对www的子域起作用。

secure bool
表明cookie只可以通过与客户建立的安全HTTPS连接进行传输。当设为TRUE时,该cookie只可以在为安全连接时进行设置,否则不行。在服务器端,同样如此,只有是安全连接时才可以发送此类cookie(比如$_SERVER["HTTPS"])

httponly bool
当为TRUE时,cookie只可以通过HTTP协议访问。这意味着cookie无法被脚本语言,比如JavaScript,使用。该设置可以有效帮助我们减少通过XSS攻击进行的身份盗窃(但并不是所有浏览器都支持),但也从事存在冲突。

返回值:

如果之前存在任何输出的话,那么setcookie将会失败,并且返回FALSE。如果setcookie成功运行,就返回TRUE。并不代表客户端是否成功接收了cookie。

例子:

<?php
$value = 'something from somewhere';

setcookie("TestCookie", $value);
setcookie("TestCookie", $value, time()+3600); /* expire in 1 hour */
setcookie("TestCookie", $value, time()+3600, "/~rasmus/", ".example.com", 1);
?>

 

——Output Control Function——

 以下是输出控制函数,这里就不详细介绍了,详细的可以查看相应链接。