В наши дни, когда выделенный канал Интернета стал нормой, не особо стоит переживать о размере страничек. Однако, все таки на это стоит обращать внимание. Если Вы хотите уменьшить нагрузку на сервер, сократить количество HTTP запросов - для этого существует несколько техник. Рассмотрим несколько PHP трюков (кеширования, сжатие).
1. Объединение CSS файлов с помощью PHP
Как веб разработчики, мы часто разделяем стили между несколькими таблицами стилей для более логичной структуры и легкого изменения в дальнейшем. Однако, это увеличивает количество запросов на сервер, что выливается в более медленную загрузку страниц. Используя PHP мы можем сразу убить двух зайцев: иметь несколько таблиц стилей, и использовать всего один запрос для обращения к ним всем.
Подготовка
Перед оптимизацией CSS файлов, нам необходимы стили для работы. Давайте создадим несколько файлов с стилями:
// main.css
// CSS для примера
body {
width: 800px;
margin: 0 auto;
color: grey;
}
#wrapper {
margin-top: 30px;
background: url(../images/cats.png);
}
// typography.css
// CSS для примера
body {
font-family: Arial, san-serif;
font-weight: bold;
}
strong {
font-size: 120%;
}
// forms.css
// CSS для примера
form {
position: relative;
top: 400px;
z-index: 99;
}
input {
height: 50px;
width: 400px;
}
PHP
Нам необходимо извлечь содержание всех файлов и соединить в определенном порядке. Значит наш скрипт должен получить имена таблиц стилей через УРЛ параметры, открыть эти файлы и соединить.
<?php
//Определяем переменные
// --- NOTE: PATHS NEED TRAILING SLASH ---
$cssPath = './css/';
if (isset($_GET['q'])) {
$files = $_GET['q'];
// Получаем массив файлов
//Давайте убедимся, что в файловых именах нет страшных символов :) .
foreach ($files as $key => $file) {
$files[$key] = str_replace(array('/', '\\', '.'), '', $file);
}
$cssData = '';
foreach ($files as $file) {
$cssFileName = $cssPath . $file . '.css';
$fileHandle = fopen($cssFileName, 'r');
$cssData .= "\n" . fread($fileHandle, filesize($cssFileName));
fclose($fileHandle);
}
}
// Скажи браузеру, что у нас CSS файл
header("Content-type: text/css");
if (isset($cssData)) {
echo $cssData;
echo "\n\n// Generated: " . date("r");
} else {
echo "// Files not avalable or no files specified.";
}
?>
Более подробно о каждой части кода
<?php
//Определяем переменные
// --- NOTE: PATHS NEED TRAILING SLASH ---
$cssPath = './css/';
if (isset($_GET['q'])) {
$files = $_GET['q'];
// Got the array of files!
//Давайте убедимся, что в файловых именах нет страшных символов :) .
foreach ($files as $key => $file) {
$files[$key] = str_replace(array('/', '\\', '.'), '', $file);
}
Этот код устанавливает путь к папке со стилями и проверяет на наличие файлов. Путь к папке должен иметь слеши вначале и в конце названия папки, так как в противном случае у нас будет масса ошибок. Далее мы проверяем каждое имя файла и удаляем точки и/или слеши.
$cssData = '';
foreach ($files as $file) {
$cssFileName = $cssPath . $file . '.css';
$fileHandle = fopen($cssFileName, 'r');
$cssData .= "\n" . fread($fileHandle, filesize($cssFileName));
fclose($fileHandle);
}
}
Теперь нам необходимо создать общую таблицу стилей из файлов. Для этого мы запускаем цикл, который просматривает массив файлов, открывает каждый файл и соединяет в единый файл. "\n" добавляет новую строку для порядка и чистоты. Функция filesize() используется для того, чтобы узнать длину файла и передать fread().
// Скажи браузеру, что у нас CSS файл
header("Content-type: text/css");
if (isset($cssData)) {
echo $cssData;echo "\n\n// Generated: " . date("r");
} else {
echo "// Files not avalable or no files specified.";
}
?>
Последняя часть кода передает все стили браузеру. Это значит, что нам необходимо сказать PHP, что мы передаем CSS информацию и что PHP должно проинформировать об этом браузер. Мы делаем это с помощью функции header(), и устанавливаем Content-type: text/css. Далее мы передаем CSS клиенту. Но перед этим проверяем наличие CSS стилей в файле. Если их нет, значит это означает, что названия CSS файлов не были переданы. Если же у нас есть файлы мы их передаем и добавляем сообщение о генерации.
Проверка
Теперь время проверить скрипт. Создаем папку и файлы в ней. Взгляните на структуру папки ниже. Если Вам необходимо другая структура, тогда не забудьте поменять пути.
Теперь загрузите все файлы в корень сайта и обратитесь к файлу index.php через браузер. Вас должна встретить фраза 'Files not available or no files specified' (файлы не доступны или не указаны). Это означет, что мы не дали названия файлов, которые необходимо соединить. Однако, хорошая новость - что все работает без ошибок. Давайте попробуем напечатать в браузере 'index.php?q[]=main'. У Вас на экране появится содержание файла main.css. Если нам необходимо извлечь несколько файлов и объединить их, нам необходимо отправить следющий запрос 'index.php?q[]=main&q[]=forms'. Как Вы видите мы можем повторять 'q[]=' сколько угодно раз. Вы можете объединить в один файл хоть 50 таблиц стилей.
Заключение
Данный метод может быть очень полезным, и иметь множество плюсов. У Вас может быть общая таблица стилей для всего сайта, и отдельная, например, для страниц с формами.
Небольшое предупреждение: если Вы поместите файл index.php в любую папку (не в папку с CSS), тогда Вам необходимо прописывать относительные пути к фоновым изображениям так, как будто index.php является Вашей таблицей стилей. Так будет думать браузер.
2. Удаление пустых строк из HTML и CSS
Многие из нас используют большое количество пустых строк при написании кода. Хорошие новости - пустые строки в PHP не передаются браузеру. Однако, передаются в HTML.
Пустые строки потребляют незначительное количество траффика. Если посещаемость сайтов большая, эта маленькая цифра может перерости в значительную. И тут нам на помощь придет PHP.
Подготовка
Ниже представлены коды для HTML и CSS файлов.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Hey a Page!</title>
<link rel="stylesheet" href="./css.css" type="text/css">
</head>
<body id="homepage">
<div id="wrapper">
<div id="header">
<h1>Kittens for sale!</h1>
<div>
There are lots of spaces here! But we need to get rid of them!
</div>
</div>
<div id="mainbody">
Lorem Ipsum dol...
</div>
</div>
</body>
</html>
body {
min-height: 800px;
background: black;
font-size: 18px;
}
#wrapper {
width: 960px;
margin: 20px auto;
padding: 15px;
}
#header h1 {
text-indent: -99999em;
background: url(../images/header.png);
display: block;
width: 100%;
height: 48px;
}
#mainbody {
font-weight: bold;
}
PHP
Преимуществом данного скрипта является то, что он может одновременно работать как с HTML, так и с CSS. Скрипт загружает файл, убирает все пустые строки, оставляет только 1 пробел, чтобы слова не соединялись в одно целое.
<?php
$fileDirectory = '';
$file = $_GET['q'];
$nameExplode = explode('.', $file);
$ext = $nameExplode[1];
$fileName = $fileDirectory . $file;
if ($ext != 'css' AND $ext != 'htm' AND $ext != 'html') {
//Проверка для хакеров
die('Hackers...!');
} else {
//Начнем
$handle = fopen($fileName, 'r');
$fileData = fread($handle, filesize($fileName));
//Чудеса регулярных выражений
$newData = preg_replace('/\s+/', ' ', $fileData);
fclose($handle);
//Выводим данные
if ($ext == 'css') {
header("Content-type: text/css");
}
echo $newData;
}
?>
Более подробно о каждой части кода
Мы получаем имя файла и проверяем его тип. Далее извлекаем все данные и убираем пробелы и пустые строки. Этот метод наиболее примитивный и не удалит все пустые строки, но он справится с большинством. И это всего несколько строк кода.
<?php
$fileDirectory = '';
$file = $_GET['q'];
$nameExplode = explode('.', $file);
$ext = $nameExplode[1];
$fileName = $fileDirectory . $file;
Этот код задает необходимые переменные. Снова, мы передаем все данные через 'q'. Тут также определяется папка для файлов.
if ($ext != 'css' AND $ext != 'htm' AND $ext != 'html') {
//Проверка для хакеровdie('Hackers...!');
} else {
Тут мы проверяем действительно ли файл является CSS или HTML.
//Начнем
$handle = fopen($fileName, 'r');
$fileData = fread($handle, filesize($fileName));
//Чудеса регулярных выражений
$newData = preg_replace('/\s+/', ' ', $fileData);
fclose($handle);
//Выводим данныеif ($ext == 'css') {
header("Content-type: text/css");
}
echo $newData;
}
?>
Этот код открывает и читает файл - и потом убирает по возможности все пустое пространство. Это достигается путем использования регулярных выражений. Находятся все пробелы, табуляции, пустые строки и заменяются на пробел.
Работает ли это?
Если Вы в браузере напечатаете 'index.php?q=css.css', то увидите одну линию CSS. Значит все работает! Если откроете исходный код страницы, то увидите такую же картину. С помощью данного метода мы уменьшили 314 символьный CSS файл до 277 символов. HTML файл с 528 до 448 символов. Неплохо для 15 строк кода.
Заключение
Это отличный пример того, как мы можем сделать много используя несколько строк кода. Если Вы взгляните на исходный код таких сайтов как Гугл, то заметите, что там практически нет пустых строк.
3. Кеширование PHP скриптов
Я покажу Вам, как настроить кеширование Ваших скриптов, используя пример выше. Цель - ускорить работу сайта. Суть очень проста - данные не будут генерироваться каждый раз при обращении к сайту. Они будут храниться в кеше.
Для добавления кеширования, нам необходимо добавить три вещи к нашему скрипту. Во первых, нам необходить собрать все данные в скрипт и сгенерировать файл уникальный для этого набора введенных данных. Во-вторых, нам необходимо найти файл с кешем и проверить насколько он "свеж". В-третьих, нам необходимо использовать кешированную копию или сгенерировать новый файл кеша для использования в дальнейшем.
Подробнее
<?php
$fileDirectory = '';
$file = $_GET['q'];
$nameExplode = explode('.', $file);
$ext = $nameExplode[1];
$fileName = $fileDirectory . $file;
//-- WE HAVE ENOUGH DATA TO GENERATE A CACHE FILE NAME HERE --
if ($ext != 'css' AND $ext != 'htm' AND $ext != 'html') {
//Check for evil people...
die('Hackers...!');
} else {
//-- WE CAN INTERCEPT AND CHECH FOR THE CACHED VERSION HERE --
//Lets get down to business
$handle = fopen($fileName, 'r');
$fileData = fread($handle, filesize($fileName));
//Now for some regex wizardry!
$newData = preg_replace('/\s+/', ' ', $fileData);
fclose($handle);
//Time to output the data.
//-- NOW WE CAN STORE THE NEW DATA IF REQUIRED AND OUTPUT THE DATA --
if ($ext == 'css') {
header("Content-type: text/css");
}
echo $newData;
}
?>
Приступим
Далее идет код кеширования для данного скрипта. Ниже будет разобрана каждая часть.
<?php
$fileDirectory = '';
$file = $_GET['q'];
$nameExplode = explode('.', $file);
$ext = $nameExplode[1];
$fileName = $fileDirectory . $file;
$cacheName = './cache/' . $nameExplode[0] . $nameExplode[1] . '.tmp';
if ($ext != 'css' AND $ext != 'htm' AND $ext != 'html') {
//Хакеры
print_r($ext);
die('Hackers...!');
} else {
if (file_exists($cacheName) AND filemtime($cacheName) > (time() - 86400)) {
$cacheHandle = fopen($cacheName, 'r');
$newData = fread($cacheHandle, filesize($cacheName));
fclose($cacheHandle);
$isCached = TRUE;
} else {
//Начнем
$handle = fopen($fileName, 'r');
$fileData = fread($handle, filesize($fileName));
//Чудеса регулярных выражений
$newData = preg_replace('/\s+/', ' ', $fileData);
fclose($handle);
//Кешируем
$cacheHandle = fopen($cacheName, 'w+');
fwrite($cacheHandle, $newData);
fclose($cacheHandle);
$isCached = FALSE;
}
//Выводим данные
if ($ext == 'css') {
header("Content-type: text/css");
if ($isCached) {
echo "// Retrieved from cache file. \n";
}
} else {
if ($isCached) {
echo '<!-- Retrieved from cache file. -->';
}
}
echo $newData;
}
?>
Объяснение
В данном скрипте была добавлена функция обновления кеша каждые 24 часа. Это удобно. Допустим, если Вы поменяли что-либо на сайте - можете подождать 24 часа или же очистить кеш.
$cacheName = './cache/' . $nameExplode[0] . $nameExplode[1] . '.tmp';
Этот отрезок кода достает название файлов и их расширения, склеивает их вместе и добавляет в кеш с правильным расширением '.tmp'.
if (file_exists($cacheName) AND filemtime($cacheName) > (time() - 86400)) {
$cacheHandle = fopen($cacheName, 'r');
$newData = fread($cacheHandle, filesize($cacheName));
fclose($cacheHandle);$isCached = TRUE;
} else {
Тут мы проверяем наличие сохраненного кеша и был ли он создан в течении последних 24 часов (значение в секундах - можно поменять на любое другое). Если оба условия выполняются, открываем файл и извлекаем содержание, чтобы заменить им результат работы скрипта. Мы также устанавливаем $isCached true для вывода дополнительных сообщений в конце.
//Lets cache!
$cacheHandle = fopen($cacheName, 'w+');
fwrite($cacheHandle, $newData);
fclose($cacheHandle);
$isCache = FALSE;
}
Кешируем результат скрипта для использования при дальнейших обращениях. Мы просто открываем файл в режиме записи, сбрасываем туда информацию и закрываем.
//Time to output the data.
if ($ext == 'css') {
header("Content-type: text/css");
if ($isCached) {
echo "// Retrieved from cache file. \n";
}
} else {
if ($isCached) {
echo '<!-- Retrieved from cache file. -->';
}
}
Эта часть скрипта была немного модифицирована, чтобы мы могли увидеть результат работы. Если содержание файла было извлечено из кеша, мы можем добавить сообщение об этом.
Пробуем
Если мы воспользуемся скриптом вновь, мы не увидим изменений до тех пор, пока не обновим страницу. Снизу увидим надпись, что файл взят из кеша.
Заключение
Умение быстро добавить простое кеширование к любому скрипты означает, что Вы идете в верном направлении. Скрипт с кешированием существенно снизит нагрузку на любой сервер.
|