Главная » Полезные статьи » Язык PHP » Управление Выводом: Caching и сжатие динамических страниц
Распечатать статью

Управление Выводом: Caching и сжатие динамических страниц

Mod_gzip — Apache модуль, который сжимает статические страницы HTML, использующие gzip, согласно IETF стандартам для браузеров, которые принимают gzip enconding (IE, Netscape, и т.д.). Mod_gzip может ускорять время загрузки страниц в 4-5, раз и я настоятельно предлагаю, чтобы Вы использовали mod_gzip на вашем webserver’е. Однако из-за недостатка механизма фильтрации между модулями в Apache 1.x.x, нет никакого способа сжать PHP вывод, используя mod_gzip. Поэтому, мы должны строить наш собственный движок сжатия в PHP. В этой статье, я объясню, как использовать функции управляющие выводом PHP, чтобы заставить ваши страницы загружаться БЫСТРО!
Введение в функции контроля вывода PHP.

Одна из лучших вещей в PHP4 — то, что Вы можете передать PHP буферу весь контент, сгенерированный в скрипте, так что ничего не будет послано браузеру, пока Вы не решите это сделать. Вы можете применять эту особенность, чтобы использовать заголовок и функции setcookie, везде, где Вы хотите в вашем скрипте. Однако, это — только небольшая часть возможностей мощных функций вывода.
void ob_start(void)
?>

Используется, чтобы сообщить PHP процессору о переадресации всего вывода на внутренний буфер. Ничего не будет послано браузеру после запроса к ob_start().
string ob_get_contents(void);
?>

Возвращает буфер вывода в строке так, что Вы можете переслать накопленный вывод браузеру (после отключения буферизации!).
int ob_get_length(void);
?>

Возвращает длину буфера вывода.
void ob_end_clean(void);
?>

Очищает буфер вывода и выключает буферизацию вывода. Вы должны использовать эту функцию до вывода контента браузеру.
void ob_implicit_flush ([int flag])

Используется, чтобы вкл\выкл неявный поток (default=off). Если включено, то «поток» выполняется для каждой print/echo или команды вывода и вывод немедленно посылается в браузер. (Директива неявной отсылки говорит PHP о том, что выводимые данные нужно автоматически передавать браузеру после вывода каждого блока данных. Ее действие эквивалентно вызовам функции flush() после каждого использования print() или echo() и после каждого HTML-блока. Включение этой директивы серьезно замедляет работу, поэтому ее рекомендуется применять лишь в отладочных целях.- из комментариев к php.ini, прим. Alexela)
Использование Контроля вывода, чтобы сжать вывод PHP.

Вы нуждаетесь в Zlib расширении, компилируемом в PHP4, чтобы сжать вывод. Если необходимо, см. Zlib расширение в PHP документации для установки инструкций.

Прежде всего, инициализируйте буферизацию вывода:
Ob_start ();
Ob_implicit_flush (0);
?>

Затем, сгенерируйте все содержание (контент), используя print, echo, или другое, что Вы хотите. Например:
print(«Hey this is a compressed output!»);
?>

После того, как страница сгенерирована, мы возвращаемся к выводу, использующему:
$contents = ob_get_contents ();
Ob_end_clean ();
?>

Затем, мы должны проверить, поддерживает ли браузер сжатие данных. Если да, браузер посылает ACCEPT_ENCODING HTTP заголовок вебсерверу в запросе. Мы можем проверить переменную $HTTP_ACCEPT_ENCODING и проверить » gzip, deflate «:

Это просто. Структурировано и достаточно ясно, чтобы использовать. Давайте посмотрим, как мы создадим gzipped вывод:
(Taken from PHP.net)
// Tell the browser that they are going to get gzip data
// Of course, you already checked if they support gzip or x-gzip
// and if they support x-gzip, you’d change the header to say
// x-gzip instead, right?
header(«Content-Encoding: gzip» );
// Display the header of the gzip file
// Thanks ck@medienkombinat.de!
// Only display this once
echo «\x1f\x8b\x08\x00\x00\x00\x00\x00″;
// Figure out the size and CRC of the original for later
$Size = strlen($contents);
$Crc = crc32($contents);
// Compress the data
$contents = gzcompress( $contents, 9);
// We can’t just output it here, since the CRC is messed up.
// If I try to «echo $contents» at this point, the compressed
// data is sent, but not completely. There are four bytes at
// the end that are a CRC. Three are sent. The last one is
// left in limbo. Also, if we «echo $contents», then the next
// byte we echo will not be sent to the client. I am not sure
// if this is a bug in 4.0.2 or not, but the best way to avoid
// this is to put the correct CRC at the end of the compressed
// data. (The one generated by gzcompress looks WAY wrong.)
// This will stop Opera from crashing, gunzip will work, and
// other browsers won’t keep loading indefinately.
//
// Strip off the old CRC (it’s there, but it won’t be displayed
// all the way — very odd)
$contents = substr($contents, 0, strlen($contents) — 4);
// Show only the compressed data
echo $contents;
// Output the CRC, then the size of the original
gzip_PrintFourChars($Crc);
gzip_PrintFourChars($Size);
// Done. You can append further data by gzcompressing
// another string and reworking the CRC and Size stuff for
// it too. Repeat until done.
function gzip_PrintFourChars($Val) {
for ($i = 0; $i < 4; $i ++) {
echo chr($Val % 256);
$Val = floor($Val / 256);
}
}
?>

Если вы хотите посмотреть это как рабочий пример, то вот весь скрипт целиком:
// Start the output buffer
ob_start();
ob_implicit_flush(0);
// Output stuff here…
print(«I’m compressed!\n»);
$contents = ob_get_contents();
ob_end_clean();
// Tell the browser that they are going to get gzip data
// Of course, you already checked if they support gzip or x-gzip
// and if they support x-gzip, you’d change the header to say
// x-gzip instead, right?

header(«Content-Encoding: gzip»);

// Display the header of the gzip file
// Thanks ck@medienkombinat.de!
// Only display this once

echo «\x1f\x8b\x08\x00\x00\x00\x00\x00″;

// Figure out the size and CRC of the original for later

$Size = strlen($contents);
$Crc = crc32($contents);

// Compress the data

$contents = gzcompress($contents, 9);

// We can’t just output it here, since the CRC is messed up.
// If I try to «echo $contents» at this point, the compressed
// data is sent, but not completely. There are four bytes at
// the end that are a CRC. Three are sent. The last one is
// left in limbo. Also, if we «echo $contents», then the next
// byte we echo will not be sent to the client. I am not sure
// if this is a bug in 4.0.2 or not, but the best way to avoid
// this is to put the correct CRC at the end of the compressed
// data. (The one generated by gzcompress looks WAY wrong.)
// This will stop Opera from crashing, gunzip will work, and
// other browsers won’t keep loading indefinately.
//
// Strip off the old CRC (it’s there, but it won’t be displayed
// all the way — very odd)

$contents = substr($contents, 0, strlen($contents) — 4);

// Show only the compressed data

echo $contents;

// Output the CRC, then the size of the original

gzip_PrintFourChars($Crc);
gzip_PrintFourChars($Size);

// Done. You can append further data by gzcompressing
// another string and reworking the CRC and Size stuff for
// it too. Repeat until done.

function gzip_PrintFourChars($Val) {
for ($i = 0; $i < 4; $i ++) {
echo chr($Val % 256);
$Val = floor($Val / 256);
}
}
?>
Кэширование PHP вывода.

Когда PHP4 не существовал, и я вынужден был использовать PHP3, я был очень заинтересован в появлении некого механизма кэширования для вывода PHP скриптов, чтобы уменьшить нагрузку базы данных, доступ к filesystem, и т.д. Не имело смысла делать это в PHP3, но с буферизацией вывода, это легко в PHP4.

Простой пример:
//Construct a filename for the requested URI

$cached_file=md5($REQUEST_URI);
if((!file_exists(«/cache/$cached_file»))||(!is_valid(«/cache/$cached_file»)))
//здесь обратите внимание на путь к файлу $cached_file, прим. Alexela
{
// is_valid validates the cache, you can check for expiration
// or particular conditions in that function.
// If there’s no file or it’s invalid we generate the output
ob_start();
ob_implicit_flush(0 );
// Output stuff here…
$contents = ob_get_contents();
ob_end_clean();
$fil=fopen($cached_file,»w+»);
//fwrite($fil,$contents,$strlen($contents));//опечатка в коде, прим. Alexela
fwrite($fil,$contents,strlen($contents));
fclose($fil);
}
//Output the file here we are sure the file exists.
readfile($cached_file);
?>

Это простой пример. Используя буферизацию вывода, Вы можете строить очень продвинутую контент генерирующую систему, используя caching механизмы, различные для различных блоков или приложений, и т.д. Это зависит от Вас.
Заключение

Функции, управляющие PHP выводом, очень полезны чтобы переадресовать вывод скрипта на буфер и затем уже манипулировать им. Сжатие буфера для браузеров уменьшает время загрузки в 4-5 раз. Это может также использоваться как caching механизм, чтобы облегчить доступ к источникам данных (базы данных или файлы) и это может иметь значение, если мы используем XML.

Думайте об этом:

Что, если мы строим движок в PHP4, используя caching, который берет данные из источников данных (xml документы и базы данных) и динамически строит содержание в xml . Мы можем тогда брать вывод xml и использовать XSLT, чтобы конвертировать к любому виду представления, которое мы хотим (HTML, wap, palm, pdf, и т.д.). PHP4, с контролем вывода и Sablotron XSLT, является совершенным для этой архитектуры. Я написал » Шикарная architectures «- описание, основанное на xml архитектуре, у которой есть много всего, что делать с функциями, описанными в этой статье. Покупайте, если это издано. Я буду также писать статью о Sablotron XSLT , как только это будет зарегистрировано и полностью годным к употреблению под PHP4. Шлите мне ваши мысли обо всем, что Вы хотите.

Источник:   codingrus.ru

Вы можете оставить комментарий, или обратную ссылку на Ваш сайт.

Оставить комментарий

Похожие статьи