美文网首页
PHP的输出缓冲区

PHP的输出缓冲区

作者: 程序员有话说 | 来源:发表于2019-02-12 15:19 被阅读0次

    1、什么是缓冲区?

    缓冲区的作用是把输入或者输出的内容先放进内存,而不显示或者读取,最本质的作用就是协调高速CPU和相对缓慢的IO设备(磁盘等)的运作。

    2、PHP在执行的时候,在什么地方有用到缓冲区?

    当执行PHP的时候,如果碰到了echo print_r之类的会输出数据的代码,PHP就会将要输出的数据放到PHP自身的缓冲区等待输出,当PHP自身的缓冲区接到指令,指示要输出缓冲区的内容时,将会把缓冲区内的数据输出到apache上,apache接受到PHP输出的数据,然后再把该数据存在到apache自身的缓冲区内等待输出,当apache接受到指令,只是要输出缓冲区的内容时,将会把缓冲区的内容输出,返回到浏览器。

    由此可见,PHP要输出数据的时候,将会经过两个缓冲区(先是自身的,然后是apache的),再返回到浏览器.

    3、缓冲区在PHP中起到什么作用?

    在使用header函数之前,输出了某些数据,这样会导致某些错误。例如 Cannot modify header information – headers already sent by;

    echo "this is test";
    header("LOCATION https://www.baidu.com");
    

    报错原因:在header之前已经输出了数据,而输出这些数据的同时,Apache将会同时发送一个响应状态到浏览器上,请求是有效的,而其后你又再次使用header函数发送http头,则会返回这个错误,HTTP头已经发送出去了,你不能对他再做修改的致命错误。

    1)使用缓冲区可以避免这个错误呢?

    因为header函数是不受缓冲区影响的,当一碰到header函数的时候,PHP马上执行apache发送这一个http头都浏览器。而输出的数据PHP打开输出缓冲区后, 这些数据将会存放在缓冲区,等待输出.这样就可以避免了之前所发生的错误。

    2)通过PHP下载大文件程序

    解决:

    1.将会在所有数据读完之后才会得到响应,降低了用户体验感。

    2.PHP的执行内存的限制。

    function readfile_chunked($filename,$retbytes=true) {
    
        $chunksize = 1*(1024*1024); // how many bytes per chunk
    
        $buffer = '';
    
        $cnt =0;
    
        // $handle = fopen($filename, 'rb');
    
        $handle = fopen($filename, 'rb');
    
        if ($handle === false) {
    
            return false;
    
        }
    
        while (!feof($handle)) {
    
            $buffer = fread($handle, $chunksize);
    
            echo $buffer;
    
            if ($retbytes) {
    
                $cnt += strlen($buffer);
    
            }
    
        }
    
            $status = fclose($handle);
    
        if ($retbytes && $status) {
    
            return $cnt; // return num. bytes delivered like readfile() does.
    
        } 
    
        return $status;
    
    } 
    

    如果开启了输出缓冲区,当PHP程序读完文件的某一段,然后马上输出到apache,然后让apache马上返回到浏览器,这样就可以减少用户等待时间;每次只读某一段,这样就可以避免了内存的限制。http://hk1.php.net/manual/zh/function.readfile.php

    3)静态文件缓存

    <?php
    
    $cacheTime = 10; //定义一个缓存过期时间  秒为单位
    
    $file = 'a.html';
    
    if(!file_exists($file) || time()-filemtime($file) > $cacheTime){
    
    ob_start();
    
    $string = ob_get_contents();
    
    file_put_contents($file,$string);
    
    ob_flush(); //刷新输出缓冲
    
    flush();
    
    }else{
    
    echo file_get_contents($file);
    
    }
    

    ob_flush是和php自身相关的,而flush操作的是apache的缓冲区,所有我们在使用这两个函数的时候,需要先执行ob_flush,再执行flush,因为我们需要先把数据从PHP上发送到apache,然后再由apache返回到浏览器。如果php还没有把数据刷新到apache,就调用了flush,则apache无任何数据返回到浏览器.

    相关文章

      网友评论

          本文标题:PHP的输出缓冲区

          本文链接:https://www.haomeiwen.com/subject/atrkeqtx.html