Що таке буферизація на виході?


Відповіді:


274

Розробка результатів для веб-розробників, Посібник для початківців :

Без буферизації виводу (за замовчуванням) ваш HTML надсилається до браузера фрагментами, як PHP обробляє ваш сценарій. З буферизацією виводу ваш HTML зберігається у змінній та надсилається до браузера як один фрагмент в кінці вашого сценарію.

Переваги буферизації вихідних даних для веб-розробників

  • Повторне включення вихідного буферування зменшує кількість часу, необхідне для завантаження та надання нашого HTML, оскільки воно не надсилається до браузера частинами, оскільки PHP обробляє HTML.
  • Всі модні речі, які ми можемо зробити з PHP-рядками, тепер ми можемо робити всю нашу HTML-сторінку як одну змінну.
  • Якщо ви коли-небудь стикалися з повідомленням "Попередження: Неможливо змінити інформацію заголовка - заголовки, які вже надіслані (виведення)" під час встановлення файлів cookie, ви будете раді дізнатись, що буферизація вихідних даних - це ваша відповідь.

6
+1. Ось ще одне корисне посилання: php.net/manual/en/function.ob-start.php - також корисний при роботі з функцією, що повторює значення, яке ви бажаєте зберегти у змінній.
Cam

Чи справді все буферизовано до кінця, чи сторінка просто зіпсується, якщо у мене є рейлінгова довга сторінка?
zedoo

5
@zedoo, якщо ви почнете буферизацію виводу ob_start(), насправді все буферно. є необов'язковий другий параметр для ob_start(), int $chunk_sizeякий, якщо встановлено, призведе до змивання буфера після будь-якого вихідного виклику, який призводить до того, що довжина буфера дорівнює або перевищує цей розмір.
сокира.

12
Якщо ви отримали "Попередження: Неможливо змінити інформацію заголовка", це означає, що вам потрібно спочатку перевірити код, оскільки включення вихідної буферизації - це виправлення симптому, а не причина. Щось пише перед тим, як настане черга. Тож я не погоджуюся, але недостатньо, щоб відповісти вниз.
Glenn Plas

5
Я бачу лише переваги використання буферизації, так чому він не включений за умовчанням у php?
Томас Бандерас

69

PHP використовує буферизацію виходів для підвищення продуктивності та виконання декількох трюків.

  • Ви можете мати PHP зберігати весь вихід у буфер і виводити все це відразу, покращуючи продуктивність мережі.

  • Ви можете отримати доступ до вмісту буфера, не надсилаючи його до браузера в певних ситуаціях.

Розглянемо цей приклад:

<?php
    ob_start( );
    phpinfo( );
    $output = ob_get_clean( );
?>

Наведений вище приклад фіксує вихід у змінну замість того, щоб надсилати її до браузера. output_buffering вимкнено за замовчуванням.

  • Ви можете використовувати буферизацію виводу в ситуаціях, коли ви хочете змінити заголовки після надсилання вмісту.

Розглянемо цей приклад:

<?php
    ob_start( );
    echo "Hello World";
    if ( $some_error )
    {
        header( "Location: error.php" );
        exit( 0 );
    }
?>

Тут є те саме питання, що і для Axe: чи не запускається буферизація вихідних даних, не відключаючи її пізніше, чи змусить ваш сценарій зіткнутися з усіма проблемами?
Edward Stumperd

1
Буфер видаляється, коли ви викликаєте один із методів промивання (наприклад, ob_flush()або ob_end_flush()). Зміст буфера також стирається, коли ваш скрипт закінчиться, різко чи іншим чином, тому не повинно виникнути проблем.
Салман

17

Я знаю, що це давнє запитання, але я хотів написати свою відповідь для учнів, які навчаються візуально. Я не зміг знайти жодної діаграми, яка б пояснювала буферизацію вихідних даних у всесвітній мережі, тому я сам створив схему в Windowsmspaint.exe .

Якщо буферизація вимкнено, то echoдані негайно відправлятимуться в браузер.

введіть тут опис зображення

Якщо буферизація виводу увімкнена, то повідомлення echoнадсилатиме дані у вихідний буфер перед тим, як надсилати їх у браузер.

введіть тут опис зображення

phpinfo

Щоб побачити, чи буферизація вихідних даних увімкнена / вимкнена, зверніться до phpinfo у розділі основної. output_bufferingДиректива повідомить вам , якщо Буферизація виводу вкл / викл.

введіть тут опис зображення У цьому випадку output_bufferingзначення становить 4096, що означає, що розмір буфера становить 4 Кб. Це також означає, що буферизація вихідних даних увімкнена на веб-сервері.

php.ini

Можна включити / вимкнути та змінити розмір буфера, змінивши значення output_bufferingдирективи. Просто знайдіть його php.ini, змініть його на вибрані вами настройки та перезапустіть веб-сервер. Ви можете знайти зразок мого php.iniнижче.

; Output buffering is a mechanism for controlling how much output data
; (excluding headers and cookies) PHP should keep internally before pushing that
; data to the client. If your application's output exceeds this setting, PHP
; will send that data in chunks of roughly the size you specify.
; Turning on this setting and managing its maximum buffer size can yield some
; interesting side-effects depending on your application and web server.
; You may be able to send headers and cookies after you've already sent output
; through print or echo. You also may see performance benefits if your server is
; emitting less packets due to buffered output versus PHP streaming the output
; as it gets it. On production servers, 4096 bytes is a good setting for performance
; reasons.
; Note: Output buffering can also be controlled via Output Buffering Control
;   functions.
; Possible Values:
;   On = Enabled and buffer is unlimited. (Use with caution)
;   Off = Disabled
;   Integer = Enables the buffer and sets its maximum size in bytes.
; Note: This directive is hardcoded to Off for the CLI SAPI
; Default Value: Off
; Development Value: 4096
; Production Value: 4096
; http://php.net/output-buffering
output_buffering = 4096

Директива output_bufferingне є єдиною налаштованою директивою щодо буферизації вихідних даних. Інші налаштовані директиви щодо буферизації виводу можна знайти тут: http://php.net/manual/en/outcontrol.configuration.php

Приклад: ob_get_clean ()

Нижче ви можете побачити, як захопити echoта маніпулювати ним, перш ніж надсилати його в браузер.

// Turn on output buffering  
ob_start();  

echo 'Hello World';  // save to output buffer

$output = ob_get_clean();  // Get content from the output buffer, and discard the output buffer ...
$output = strtoupper($output); // manipulate the output  

echo $output;  // send to output stream / Browser

// OUTPUT:  
HELLO WORLD

Приклади: Hackingwithphp.com

Більше інформації про вихідний буфер із прикладами можна знайти тут:

http://www.hackingwithphp.com/13/0/0/output-buffering


9

Функції управління виходом дозволяють контролювати, коли вихід надсилається із сценарію. Це може бути корисно в декількох різних ситуаціях, особливо якщо вам потрібно надсилати заголовки до браузера після того, як ваш сценарій почав виводити дані. Функції управління виходом не впливають на заголовки, що надсилаються за допомогою header () або setcookie (), лише на функції, такі як echo () та дані між блоками коду PHP.

http://php.net/manual/en/book.outcontrol.php

Більше ресурсів:

Буферизація на виході за допомогою PHP



1
ob_start();  // turns on output buffering
$foo->bar();  // all output goes only to buffer
ob_clean();  // delete the contents of the buffer, but remains buffering active
$foo->render(); // output goes to buffer
ob_flush(); // send buffer output
$none = ob_get_contents();  // buffer content is now an empty string
ob_end_clean();  // turn off output buffering

Буфери можуть бути вкладені, тому, коли один буфер активний, інший ob_start()активує новий буфер. Отже, ob_end_flush()і ob_flush()насправді не надсилають буфер на вихід, а на батьківський буфер. І лише тоді, коли немає батьківського буфера, вміст надсилається до браузера або терміналу.

Чудово пояснено тут: https://phpfashion.com/everything-about-output-buffering-in-php


0

ОНОВЛЕННЯ 2019. Якщо у вас є виділений сервер і SSD або краще NVM, 3,5 ГГц. Не слід використовувати буферизацію для швидшого завантаження веб-сайту за 100 мс-150 мс.

Мережа Becouse повільно, ніж закуповує сценарій у 2019 році з серверами продуктивності (сервери, пам'ять, диск) та з включенням APC PHP :) Для генерованого сценарію іноді потрібно лише 70 мс, інший час - лише мережа займає час, від 10 мс до 150 мс від розташованого користувач-сервер.

тому, якщо ви хочете швидко пройти 150 мс, буферизація зробить уповільнення, тому що вам потрібні додаткові дані буфера збору, це зробить додаткові витрати. 10 років тому, коли сервер робив сценарій 1s, це було корисно.

Будьте уважні, якщо ви хочете, щоб jpg для завантаження використовував jpg, його можна автоматично автоматизувати і перестати надсилати.

Ура.

Ви можете зробити швидку річку або Ви можете зробити безпечно tama :)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.