При разработке веб проектов наступает тот момент, когда "создатель" и его детище сталкиваются с т.н. высокими нагрузками, замедляющими работу всего проекта. Чтобы этого избежать, разработчики стали придумывать вещи, снижающие нагрузку на оборудование. Одной из этих вещей и явилось всевозможное кеширование или сжатие необходимых файлов/данных/страниц.
Пожалуй, начну я с самого просто и буду двигаться вперед к сложному по нарастающей.
Первым делом поговорим о так называемом "GZIP compression" - GZIP обеспечивает сжатие без потерь, иными словами, исходные данные можно полностью восстановить при распаковке. Прочесть об этом подробнее можно
здесь.
Предоставлю рабочий код:
PHP код:
class g_ZIP
{
public function start_gZIP()
{
ob_start();
ob_implicit_flush(0);
}
public function output_gZIP($compress = true, $use_etag = true, $send_body = true)
{
$min_gz_size = 1024;
$page = ob_get_contents();
$length = strlen($page);
ob_end_clean();
if ($compress && extension_loaded('zlib') && (strlen($page) > $min_gz_size) && isset($globals['http_server_vars']['http_accept_encoding']))
{
$ae = explode(',', str_replace(' ', '', $globals['http_server_vars']['http_accept_encoding']));
$enc = false;
if (in_array('gzip', $ae))
$enc = 'gzip';
else if (in_array('x-gzip', $ae))
$enc = 'x-gzip';
if ($enc)
{
$length = strlen($page);
header('content-encoding: ' . $enc);
header('vary: accept-encoding');
} else
$compress = false;
} else
$compress = false;
if ($use_etag)
{
$etag = '"' . md5($page) . '"';
header('etag: ' . $etag);
if (isset($globals['http_server_vars']['http_if_none_match']))
{
$inm = explode(',', $globals['http_server_vars']['http_if_none_match']);
foreach ($inm as $i)
{
if (trim($i) == $etag)
{
header('http/1.0 304 not modified');
$send_body = false;
break;
}
}
}
}
if ($send_body)
{
header('content-length: ' . $length);
echo $page;
}
}
}
Использовать данный код на практике можно смело. Делается это вот так:
PHP код:
$g_ZIP = new g_ZIP();
$g_ZIP->start_gZIP();
// Тело документа/страницы
$g_ZIP->output_gZIP();
P.S. Код писался не мной и пояснять его работу я не буду, благо, во всемирной паутине хватает различного материала.
Так же можно использовать следующие манипуляции с файлом
.htaccess ( подробнее об этом файле можно узнать
здесь. ) :
PHP код:
<IfModule mod_gzip.c>
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file \.(html?|txt|css|js|php|pl)$
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text\.*
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_exclude mime ^image\.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</IfModule>
Однако, можно зайти еще дальше и использовать вот такие вот "извращения":
PHP код:
class pages_Cache
{
var $ID;
var $path;
var $file_cache;
var $full_url_cache;
public function _cacheInit($ID, $path, $file_cache)
{
if(!is_writable($path))
chmod($path, 0644); // Доступ на запись и чтение для владельца, доступ на чтение для других
$this->ID = $ID;
$this->full_url_cache = $path.$file_cache;
if(file_exists($this->full_url_cache))
{
echo file_get_contents($this->full_url_cache);
exit;
} else
ob_start();
}
public function _cacheStop_and_Write()
{
$handle = fopen($this->full_url_cache, 'w'); // Открываем файл для записи и стираем его содержимое
fwrite($handle, ob_get_contents()); // Сохраняем всё содержимое буфера в файл
fclose($handle); // Закрываем файл
ob_end_flush(); // Выводим страницу в браузере
}
public function _clearCache($file)
{
@unlink($file);
}
public function _cleanCacheDir($dir)
{
$files = glob($dir."/*");
if(count($files) > 0)
{
foreach ($files as $file)
{
if(file_exists($file))
{
unlink($file);
}
}
}
}
}
К примеру у вас есть страница с некоторыми данными, которые обновляются крайне редко и вам не хотелось бы нагружать сервер лишними запросами -> этот код, думаю, будет лучшим решением данной проблемы.
Как же он работает: при первой загрузке страницы, код проверяет, есть ли данный кеш с таким ID ( к примеру ) на сервере, если да, то данные не будут читаться дальше из базы, а просто вам будет показано то, что уже записано в файл. Если же кеша нет на сервере, то данные запишутся в файл->создастся кеш и будет происходить то, что было описано выше. Прошу прощения за примитивный пример.
Как же это использовать:
PHP код:
$pages_Cache = new pages_Cache();
$pages_Cache->_cacheInit($_GET_ID, rtrim($_SERVER['DOCUMENT_ROOT'],'/')."/cache/news/", "cache_news_".$_GET_ID.".tmp");
//Тело документа/страницы
$pages_Cache->_cacheStop_and_Write();
Как же обновить кеш? Спросите вы. Очень легко. К примеру: у нас уже есть готовая новость, выведенная на главную страницу и добавленная в кеш. Вдруг произошла необходимость что-то подкорректировать в ее содержании->просто добавляем вот этот код в необходимое место ( где в коде происходит "редактирование" ) и пользователи свободно увидят внесенные вами изменения, а кеш успешно сам обновится:
PHP код:
$pages_Cache->_clearCache(rtrim($_SERVER['DOCUMENT_ROOT'],'/')."/cache/news/cache_news_".$_GET_ID.".tmp");