Как заставить Apache работать или как я реализую создание миниатюр изображений в своих проектах

в 11:35, , рубрики: Apache, htaccess, thumbnail

Здравствуйте.

Занимаясь созданием различных интернет-проектов уже порядочное время, часто был просто возмущён одним фактом — не все элементы системы несут на себе равную нагрузку. Я всегда придерживался мнения, что каждый элемент системы, будь то интерпретатор того или иного языка для сайта, или база данных, или даже сам HTTP сервер, должен брать на себя максимально возможную нагрузку, дабы облегчить участь остальных элементов системы. Да и сами приложения для своих проектов всегда старался максимально разгрузить.

Сейчас же мне хотелось бы поделиться своим опытом в том, как «озадачить» Apache при создании миниатюр изображений (Thumbnails).

При «переделках» сайтов с различными вариантами миниатюризации изображений долгое время сталкивался и всегда очень разочаровывался в их устройстве. Практически все решения заключались в работе скриптов и уже скрипты искали исходники для миниатюризации и генерировали заголовки, если таковое не найдено. А когда же я увидел реализацию миниатюр в CMS MODX через phpThumbOf, то невольно даже прослезился.

Так уж случилось, что пришлось делать интерне- магазин на выше упомянутой CMS. Задачка, если честно, не из простых, но самым щекотливым моментом стала генерация миниатюр. Товары и изображения к ним выгружаются из 1С и ни о какой оптимизации и стандартизации в отношении изображений, как вы, наверное, уже понимаете, и речи быть не может. В этом плане в большинстве случаев 1С можно назвать одним словом — «помойка». Каждый пихает туда как может и тянет откуда получается. Так или иначе, изображения товаров есть и их много. Также помимо изображений товаров должна быть уйма других — фото под различные акции, мероприятия… Да что уж говорить — должно быть много изображений.

Поскольку перспектива использования системной phpThumbOf меня не прельщала, так как генерация миниатюр во время генерации страницы — слишком уж дико, да и чистить миниатюры при очередном обмене данными с 1С становилось бы проблемой, я начал поиск решения, соответствующего моему концепту «работать должны все».

Суть идеи была проста:

  • вынести миниатюризатор из CMS, дабы не перегружать интерпретатор лишним и зачастую ненужным кодом;
  • иметь в минаитюризаторе не одно, а множество правил преобразования, и подгружать их по маске;
  • не использовать миниатюризатор вхолостую, т.е. не пытаться определить в нём: есть ли миниатюра или ее исходник, или нет;
  • переложить часть работы миниатюризатора на сервер Apache через .htaccess;
  • и сделать чтобы миниатюры создавались по первому требованию, а не принудительно всегда.

Реализацию самого миниатюризатора на PHP я пропущу, т.к. не о нем речь, а вот самим концептом поделюсь. Думаю, пригодится он многим.

Итак, шаг первый: хранение изображений и миниатюр при наличии множества правил преобразования исходников.

У нас есть папка на сайте, в которой лежат все изображения. Пусть это будет папка «images». В этой папке есть множество подкаталогов с картинками на различные тематики.

Создадим в ней подкаталог для хранения миниатюр. Пусть это будет каталог «thumb».

Внутри этого каталога будут лежать подкаталоги с миниатюрами. Каждый подкаталог соответствует определённому правилу преобразования исходного изображения. Пусть это будут подкаталоги «a,b,c,d». В каждом из них будут лежать изображения из каталога «images» и ниже, пропущенные через миниатюризатор с использованием общего правила преобразования.

Таким образом, для изображения «/images/folder1/image1.jpg» после преобразования по шаблону «a» будет миниатюра «/images/thumb/a/folder1/image1.jpg».

Шаг второй: добавляем сам миниатюризатор.

Я просто кладу скрипт с вызовом миниатюризатора в папку изображений. Пусть это будет «/images/thumb.php». Хотя никто не мешает поместить его где угодно. Главное не забыть отразить это в «.htaccess» в RewriteBase и RewriteRule.

И в конце: даём пинок серверу Apache.

Создаем файлик «/images/.htaccess» со следующим содержанием:

RewriteEngine On
RewriteBase /images/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} ^/([^/]+)/thumb/([^/]+)(/.+)?/(.+).(jpe?g|png|gif|svgz?|tiff?)$
RewriteCond %{DOCUMENT_ROOT}/%1%3/%4.%5 –f
RewriteRule ^(.*)$ thumb.php [L,QSA]

Таким содержимым мы заставляем Apache немного подумать запускать ли миниатюризатор или нет.

Сервер сперва проверит есть ли вообще запрашиваемое изображение. Если такого нет, то проверит, является ли это запросом миниатюры. Если это должна быть миниатюра, то он должен проверить есть ли исходник для запрашиваемой миниатюры. Если исходник существует, то он запускает миниатюризатор.

Ложь на любом этапе проверки запускает стандартную логику сервера. Т.е. если запрашиваемое изображение есть – он сам его отдает; если это не запрос миниатюры или нет исходника для запрашиваемой миниатюры, то Apache вернёт статус 404 «не найдено».

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

А теперь усложним задачу для сервера.

Допустим, у меня есть SVG изображение «/images/svgs/logo.svg» а в кэше хочу иметь миниатюру в формате PNG.
По выше указанной схеме Apache просто не найдёт исходника для «/images/thumb/b/svgs/logo.png», т.к. сервер ищет исходник с тем же расширением.

Можно заставить Apache подумать побольше:

RewriteEngine On
RewriteBase /images/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} ^/([^/]+)/thumb/([^/]+)(/.+)?/(.+).(jpe?g|png|gif|svgz?|tiff?)$
RewriteCond %{DOCUMENT_ROOT}/%1%3/%4.jpg -f [OR]
RewriteCond %{DOCUMENT_ROOT}/%1%3/%4.jpeg -f [OR]
RewriteCond %{DOCUMENT_ROOT}/%1%3/%4.tif -f [OR]
RewriteCond %{DOCUMENT_ROOT}/%1%3/%4.tiff -f [OR]
RewriteCond %{DOCUMENT_ROOT}/%1%3/%4.gif -f [OR]
RewriteCond %{DOCUMENT_ROOT}/%1%3/%4.bmp -f [OR]
RewriteCond %{DOCUMENT_ROOT}/%1%3/%4.png -f [OR]
RewriteCond %{DOCUMENT_ROOT}/%1%3/%4.svg -f [OR]
RewriteCond %{DOCUMENT_ROOT}/%1%3/%4.svgz -f
RewriteRule ^(.*)$ thumb.php [L,QSA]

Теперь, прежде чем отправить наш запрос миниатюры скрипту, Apache попробует найти исходник для запрашиваемой миниатюры в другом формате. Он просто переберёт все возможные расширения для этого файла и если не нашел соответствия опять же вернёт нам 404 «не найдено».

Теперь при запуске миниатюризатора нам достаточно лишь проверить наличие переменной «REDIRECT_URL», чтобы удостовериться, что это редирект, а не прямой запуск скрипта. В остальном миниатюризатор уже точно знает, что исходник есть. Да и куда положить результат своей работы он уже знает, и откуда взять исходник. Все в одной и той же переменной окружения «REDIRECT_URL».

Обнулять кэш очень легко – указываем папку исходников, для которой нужно очистить кэш, программа подгрузит наименования шаблонов и прочистит кэш для каждого шаблона преобразований. Также можно прочистить только для одного шаблона. А для обновления кэша при обмене с 1С просто проверяем контрольные суммы имеющегося изображения и входящего, и при несоответствии заменяем исходник и вычищаем все его миниатюры.

Автор: ugodrus

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js