28.8. Сжатие вывода
Несмотря на доступность широкополосного персонального доступа в Internet, многие Web-узлы по-прежнему ориентируются на пользователей, имеющих доступ к сети по телефонным сетям. Если вам доводилось работать с таким доступом, вероятно, вы знаете, что количество страниц Web-узла непосредственно влияет на время, которое будет ожидать пользователь до появления его на экране. Если не принимать в расчет производительность Web-сервера, время доставки содержимого Web-узла пользователю остается на совести сети. Уменьшение размера содержимого уменьшает влияние производительности сети на общее время ответа.
Отказ от определенных элементов Web-узла нельзя считать приемлемым решением, т.е. Web-дизайнерам также приходится оптимизировать проект в соответствии с требованиями к приложению. Одним из практических решений этой проблемы можно считать сжатие, и здесь на помощь приходит PHP.
Сжатие вывода PHP основывается на том, что большинство популярных браузеров (включая Internet Explorer, Netscape Navigator и Mozilla) незаметно для пользователя распаковывает сжатые страницы. Такие браузеры отправляют в своем HTTP-запросе специальную команду (Accept-Encoding: deflate, gzip), которая показывает браузеру, что ему известно, каким образом будет обрабатываться содержимое. Большинство серверов никак не обрабатывает эту информацию, но с PHP вы сможете преобразовать их в небольшие страницы и уменьшить время их загрузки. Размеры документов можно уменьшить в 2-10 раз!
Сжатие ввода обнаруживает специальную запись в запросе браузера, который будет незаметно сжимать любой вывод, сделанный приложением. Для того чтобы воспользоваться сжатием вывода (только для браузеров, которые поддерживают такую возможность), активизируйте директиву zlib.output_compression в файле php.ini. Если необходимо сжать только одну страницу, используйте функцию PHP ob_start. Например, команда ob_start("ob_gzhandler", 4096) активизирует сжатие и буферизацию вывода. Заметим, что в PHP реализован механизм сжатия в самом начале работы механизма буферизации. В отличие от обычной порционной буферизации вывода, при котором просто пересылается содержимое буфера вывода при каждом его заполнении, при активизированном сжатии вывода содержимое буфера при каждой передаче проходит через специальный компрессионный буфер. Размер буфера непосредственно влияет на эффективность сжатия, и для буферов меньшего размера показатели сжатия ухудшаются. Если используются буферы большего размера, то показатели сжатия обычно улучшаются в основном за счет повышения накладных расходов, необходимых для распределения памяти. Как и при обычной буферизации вывода, размер буфера, равный 4096 байт, является оптимальным. Если нет веской причины изменения этого значения, необходимо придерживаться значений, заданных по умолчанию.
Поскольку при сжатии информации потребляется много процессорного времени, имеет смысл пользоваться им только в следующих случаях:
• страницы имеют большой объем информации;
• большинство пользователей имеют доступ к вашему Web-узлу через медленные линии;
• процессор, на котором работает ваш Web-сервер, имеет неполную загрузку.
Если не все из перечисленных факторов имеют отношение к вашему случаю, активизация функции сжатия вывода действительно позволяет уменьшить общую производительность. Если вы заинтересовались возможностью использования функции сжатия вывода без необходимости платить цену накладными расходами процессорного времени, рассмотрите возможности такого инструмента, как Zend Performance Suite. Эта программа выполняет сжатие вывода с кэшированием содержимого, а это значит, что можно воспользоваться всеми преимуществами сжатия вывода, без необходимости сжатия данных всякий раз. 
28.9. Избегайте использования функции eval
Перед тем как углубиться в детали, запомните, что "eval( ) - это зло" ("eval( ) is evil'). Необходимо любыми способами избегать применения функции eval, так как она слишком замедляет работу при низком быстродействии, поскольку, для того чтобы выполнить код, необходимо запускать компонент компиляции в рабочем цикле процессора Zend Engine, потребляющем много ресурсов. В большинстве ситуаций обращение к функции eval можно заменить аналогичным кодом, в котором функция eval не используется. Наиболее общий случай, когда функция eval может быть замещена более быстрым кодом, - это когда она используется для динамического доступа к переменным (листинг 28.2).

Листинг 28.2. Необязательное использование функции eval

<?php
function assign($varname, $value) {
eval("global $varname; $varname = $value;");
}
for($i=0; $i<100;
{
assign("foo", 5); print($foo);
}

В приведенном примере функция assign может использоваться для присвоения значений переменным, когда есть имя переменной и нет самой переменной. В нашем случае строка eval распространяет свое действие на global $foo; $foo = $value;, которая присваивает глобальной переменной foo значение 5, а затем при ее распечатке получим, как ожидалось, значение 5. Аналогичный результат можно получить и с помощью косвенной ссылки (листинг 28.3).

Листинг 28.3. Устранение ненужного использования функции eval

<?php
function assign($varname, $value)
{
global $varname; $varname = $value;
}
for($i=0; $i<100; $i++)
{
assign("foo", 5); print($foo);
}
?>