对于PHP的缓冲模式查询大家都知道,下面列举的例子是如何执行非缓冲查询API。

关于缓冲查询和无缓冲查询MySQL的客户端有两种类型的查询:缓冲查询:将接收查询的结果并把他们存储在客户端的缓存中,而且接下来获取行记录的请求仅仅从本地内获取。优点:可以在结果集中自由地移动“当前行”的指针,这样很容易找到,因为结果是存在客户端的。缺点:需要额外的内存来存储这些结果集,而且需要大量的内存,另外,php中用来运行查询的函数会一直到所有的结果都接收才会返回值。

1.先要有一张表,显示出表中的数据:

bufferbuffer是一个内存地址空间,Linux系统默认大小一般为4096,即一个内存页。主要用于存储速度不同步的设备或者优先级不同的设备之间传办理数据的区域。通过buffer,可以使进程这间的相互等待变少。这里说一个通俗一点的例子,你打开文本编辑器编辑一个文件的时候,你每输入一个字符,操作系统并不会立即把这个字符直接写入到磁盘,而是先写入到buffer,当写满了一个buffer的时候,才会把buffer中的数据写入磁盘,当然当调用内核函数flush()的时候,强制要求把buffer中的脏数据写回磁盘。

本文实例讲述了php缓冲输出用法。分享给大家供大家参考。具体分析如下:

非缓冲查询方法一: mysqli

无缓冲查询:会限制你通过严格的顺序访问查询结果。但他不需要额外的内存来存储整个结果集。你可以在MySQL服务器开始返回值的时候就开始获取而处理或显示数据行。当使用无缓冲结果集时,必须使用mysql_fetch_row函数获取所以的数据行,或者在给服务器发送其他任何命令前用mysql_free_result函数关闭结果集。

 无标题文档

同样的道理,当执行echo,print的时候,输出并没有立即通过tcp传给客户端浏览器显示,
而是将数据写入php buffer。php output_buffering机制,意味在tcp
buffer之前,建立了一新的队列,数据必须经过该队列。当一个php
buffer写满的时候,脚本进程会将php
buffer中的输出数据交给系统内核交由tcp传给浏览器显示。所以,数据会依次写到这几个地方:echo/print
-> php buffer -> tcp buffer -> browser

ob_start([string output_callback])- 打开输出缓冲区

query("SELECT Name FROM City", MYSQLI_USE_RESULT);if  { while ($row = $uresult->fetch_assoc { echo $row['Name'] . PHP_EOL; }}$uresult->close();?>

哪种类型的查询好?最好的根据是具体情况而定,无缓冲查询在结果集巨大的时为你节省大量的临时内存,而且查询不需要排序时,php在MySQL数据库实际上还在处理时就可以获得第一个数据行。缓存查询便于寻找,它可以提供一个全面的寻找加速。因为每一个单独的查询的都会快读结束,mysql快速的获取结果集并存放在内存中,而不是在处理PHP代码时保持查询为可用的。另外一个无缓冲查询的限制是在所有的数据行都被读取或者结果集用mysqli_free_result释放之前,你将无法向服务器发送任何命令。

编号

php output_buffering默认情况下,php
buffer是开启的,而且该buffer默认值是4096,即4kb。你可以通过在php.ini配置文件中找到output_buffering配置.当echo,print等输出用户数据的时候,输出数据都会写入到php
output_buffering中,直到output_buffering写满,会将这些数据通过tcp传送给浏览器显示。你也可以通过ob_start()手动激活php
output_buffering机制,使得即便输出超过了4kb数据,也不真的把数据交给tcp传给浏览器,因为ob_start()将php
buffer空间设置到了足够大。只有直到脚本结束,或者调用ob_end_flush函数,才会把数据发送给客户端浏览器。

所有的输出信息不在直接发送到浏览器,而是保存在输出缓冲区里面,可选得回调函数用于处理输出结果信息.

非缓冲查询方法二: pdo_mysql

PHP+MySQL缓冲查询和无缓冲查询PHP MySQL查询默认使用缓冲模式.
也就是说查询结果将一次性从MySQL传输到PHP进程内存中,
这时可以统计结果集的行数,以及移动结果集指针.
缓冲模式下,如果结果集很大,那么PHP进程也会占用大量的内存,
直到结果集被unset或者free.

姓名

1.当output_buffering=4096,并且输出较少数据复制代码 代码如下:

ob_end_flush – 结束输出缓冲区的内容,关闭输出缓冲区

setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);$uresult = $pdo->query("SELECT Name FROM City");if  { while ($row = $uresult->fetch { echo $row['Name'] . PHP_EOL; }}?>

store_result用于缓冲模式,所有结果一次性存储到PHP进程中:

电话

2.当output_buffering=0,并且输出较少数据复制代码 代码如下:

复制代码 代码如下:ob_start();
//打开缓冲区 echo “hello world”; //输出内容 $out=ob_get_clean();
//获得缓冲区内容并且结束缓冲区 $out=strtolower; //将字符转换为小写
var_dump; //输出结果 // if(!function_exists //判断函数是否被定义 {
function ob_clean() //定义函数 { if { return ob_start(); }
trigger_error failed to delete buffer.no buffer to
delete.”,e_user_notice); return false; } } // header(‘content-type:
multipart/x-mixed-replace;boundary=endofsection’); //发送标头 print
“n–endofsectionn”; //输出内容 $pmt=array; //定义数组 for
//通过循环进行操作 { sleep; //暂停执行 print “content-type:
text/plainnn”; //输出内容 print “part $it”.$pmt[$i % 4]; //输出内容
print “–endofsectionn”; //输出内容 ob_flush; //刷新输出缓冲 } print
“content-type: text/plainnn”; //输出内容 print “the endn”; //输出内容
print “–endofsection–n”; //输出内容

非缓冲查询方法三: mysql

mysqli::query MYSQLI_STORE_RESULT mysqli::store_result mysqli_stmt::store_result 

分组

3.当output_buffering=4096.,输出数据大于一个buffer,不调用ob_start()复制代码 代码如下:#//创建一个4kb大小的文件$dd
if=/dev/zero of=f4096 bs=4096 count=1

希望本文所述对大家的php程序设计有所帮助。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

如果PHP的MySQL数据库驱动底层用的是libmysqlclient,那么memory_limit不能统计到结果集占用的内存,
除非结果集已经赋值给PHP变量,如果底层使用mysqlnd作为驱动时则可以统计到(PHP从5.4开始底层默认使用mysqlnd).
无缓冲模式下执行的查询将会返回一个resource资源引用,位于MySQL的查询结果等待PHP获取.
无缓冲模式下,PHP进程占用的内存很少,但会增大MySQL服务器的负载.
在PHP取回所有结果前,在当前数据库连接下不能发送其他的查询请求.

query; //传值 while ($attr = $r->fetch_row { echo “

4.当output_buffering=4096, 输出数据大于一个tcp buffer,
调用ob_start()
复制代码 代码如下:output
buffering函数

use_result表示无缓冲查询:

{$attr[0]}

1.ob_get_level**返回输出缓冲机制的嵌套级别,可以防止模板重复嵌套自己。

mysqli::query MYSQLI_USE_RESULT mysqli::use_result 

{$attr[1]}

1.ob_start激活output_buffering机制。一旦激活,脚本输出不再直接出给浏览器,而是先暂时写入php
buffer内存区域。php默认开启output_buffering机制,只不过,通过调用ob_start()函数据output_buffering值扩展到足够大。也可以指定$chunk_size来指定output_buffering的值。$chunk_size默认值是0,表示直到脚本运行结束,php
buffer中的数据才会发送到浏览器。如果你设置了$chunk_size的大小,则表示只要buffer中数据长度达到了该值,就会将buffer中的数据发送给浏览器。当然,你可以通过指定$ouput_callback,来处理buffer中的数据。比如函数ob_gzhandler,将buffer中的数据压缩后再传送给浏览器。2.ob_get_contents获取一份php
buffer中的数据拷贝。值得注意的是,你应该在ob_end_clean()函数调用之前调用该函数,否则ob_get_contents()返回一个空字符中。3.ob_end_flush与ob_end_clean这二个函数有点相似,都会关闭ouptu_buffering机制。但不同的是,ob_end_flush只是把php
buffer中的数据冲到客户端浏览器,而ob_clean_clean将php
bufeer中的数据清空,但不发送给客户端浏览器。ob_end_flush调用之后,php
buffer中的数据依然存在,ob_get_contents()依然可以获取php
buffer中的数据拷贝。而ob_end_clean()调用之后ob_get_contents()取到的是空字符串,同时浏览器也接收不到输出,即没有任何输出。惯用案例常常在一些模板引擎和页面文件缓存中看到ob_start()使用。下面湿CI中加载模板的程序代码:复制代码 代码如下:/* * Buffer the output * * We buffer
the output for two reasons: * 1. Speed. You get a significant speed
boost. * 2. So that the final rendered template can be *
post-processed by the output class. Why do we * need post processing?
For one thing, in order to * show the elapsed page load time. Unless we
* can intercept the content right before it’s sent to * the browser
and then stop the timer it won’t be accurate. */ob_start();// If the
PHP installation does not support short tags we’ll// do a little string
replacement, changing the short tags// to standard PHP echo
statements.if @ini_get === FALSE AND config_item == TRUE){
//替换短标记=***>echo
eval(‘?>’.preg_replace(“/;*\s*\?>/”, “; ?>”,
str_replace(‘=’, ‘ $this->_ci_ob_level +
1){ob_end_flush();}else{
//将模板内容添加到输出流中$_ci_CI->output->append_output;
//清除buffer@ob_end_clean();}

总结:
当结果集不大时,或者需要在读取所有行前获取结果集行数时,使用缓冲查询.
当结果集很大时,使用无缓冲查询,避免PHP进程占用大量的内存.

{$attr[2]}

$rs = $mysqli->query("SELECT * FROM City", MYSQLI_USE_RESULT); $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); $rs = $pdo->query; 

{$attr[3]}

默认情况下,mysqli_stmt的SELECT查询结果将留在MySQL服务器上,等待fetch方法把记录逐条取回到PHP程序中,这样做会降低性能,但能节省内存.
如果需要对所有记录进行处理,可以调用mysqli_stmt::store_result,把所有结果一次性全部传回到PHP程序中,
这样做更高效,能减轻MySQL服务器的负担,虽然内存占用会多一些.
如果获取SELECT语句查找到了多少条记录,可以用 mysqli_stmt::$num_rows
获取. 这个属性只有在提前执行过 mysqli_stmt::store_result
方法,将全部查询结果传回到PHP程序中的情况下才可以使用. 对比
mysqli_result::$num_rows 则不没有这个限制. 用
mysqli_stmt::free_result 关闭 mysqli_stmt::store_result:

“; } ?>

$stmt->store_result(); echo $stmt->num_rows; $stmt->free_result(); 

2.再来个from表单,让用户输入,点击查询:

mysqli_stmt::store_result能让mysqli_stmt::fetch更高效,但也需要用mysqli_stmt::free_result显式关闭.
可以用mysqli_stmt::get_result拿到结果集对象$result,然后mysqli_result::fetch_all拿到查询数组$results:

query //开始判断 { //$attr已经接收到了值,现在只需要获取他的索引就行了 while ($attr = $r->fetch_row { //关键字特殊查询 $str = str_replace($name,"{$name}",$attr[1]); //查找替换如ctrl+f //substr_replace; 截取字符串 $gname = "select gname from groups WHERE gid='{$attr[3]}'"; //分组表中的gid,和我点击的 $nresult = $db->query; $gname = $nresult->fetch_row(); $nation = $gname[0]; echo " {$attr[0]}
$result = $stmt->get_result(); $results = $result->fetch_all; 

{$str}

整理一下相关参数:

{$attr[2]}

mysqli::query//执行SQL,成功返回mysqli_result(SELECT,SHOW,DESCRIBE操作)对象或TRUE,失败返回FALSE.用mysqli::close关闭.mysqli::prepare//预处理SQL,成功返回statement对象,失败返回FALSE.mysqli_stmt::execute//执行SQL.用mysqli_stmt::close关闭.mysqli_stmt::store_result//取回全部查询结果(SELECT,SHOW,DESCRIBE,EXPLAIN)到PHP,可选.用mysqli_stmt::free_result关闭.mysqli_stmt::bind_result//把prepare和execute产生的结构绑定结果到变量,然后在mysqli_stmt::fetch中把这些变量输出或赋值.mysqli_stmt::fetch//每次返回结果集的一条,赋值给mysqli_stmt::bind_result绑定的变量.mysqli_stmt::get_result//获得结果对象,然后调用mysqli_result::fetch_all就能返回结果集数组.mysqlnd下可用.mysqli_result::fetch_all//返回一个结果集数组,MYSQLI_ASSOC,MYSQLI_BOTH),用mysqli_result::close关闭.mysqlnd下可用.mysqli_result::fetch_array//每次返回结果集的一条,包含一个一维的数字数组和关联数组.mysqli_result::fetch_assoc//每次返回结果集的一条,即一个一维的关联数组.mysqli_result::fetch_row//每次返回结果集的一条,即一个一维的数字数组.

{$nation}

?>

这样:有几个条件就做几个条件变量,第一个条件不为空就执行的第一个条件,第二个条件不为空执行的第二个条件,两个都为空就是查寻所有的数据

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图