Ни один сайт не может обойтись без генерации миниатюр изображений. В интернете можно найти миллион статей на эту тему. Возможно, кому-то пригодится и это решение.
Требования:
- Изображения хранятся на удаленных серверах. У нас есть только ссылки на эти изображения
- Миниатюра должна формироваться любого заданного размера в момент непосредственного обращения к ней
- Должна быть предусмотрена защита от вредителей
- Миниатюра должна храниться на Amazon S3 и быть доступна по поддомену основного сайта. Количество бакетов на S3 и соответственно поддоменов неограничено
Реализация:
Допустим, что имя нашего сайта domain.com
1) На Amazon S3 создаем 4 бакета с названиями ic1.domain.com, ic2.domain.com, ic3.domain.com, ic4.domain.com(названия поддоменов могут быть разными, в нашем случае – это сокращение от image cache)
2) Заходим в настройки каждого бакета и ставим галочку напротив Enable website hosting
3) В поле Edit Redirection Rules прописываем правила для редиректов с несуществующих страниц:
<RoutingRules> <RoutingRule> <Condition> <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals> </Condition> <Redirect> <HostName>domain.com</HostName> <ReplaceKeyPrefixWith>s3/thumbs/</ReplaceKeyPrefixWith> </Redirect> </RoutingRule> <RoutingRule> <Condition> <HttpErrorCodeReturnedEquals>403</HttpErrorCodeReturnedEquals> </Condition> <Redirect> <HostName>domain.com</HostName> <ReplaceKeyPrefixWith>s3/thumbs/</ReplaceKeyPrefixWith> </Redirect> </RoutingRule> </RoutingRules>
4) Заходим в панель управления доменным именем domain.com и создаем поддомены, аналогичные названиям бакетов. В IN A записи прописываем Endpoint из настроек бакета.
Что мы только что сделали:
Создали 4 поддомена, на которых будут храниться миниатюры. Каждая миниатюра будет иметь адрес типа:ic1.domain.com/miniatura.jpg
Как только к этому файлу будет первое обращение, Amazon увидит, что такого файла в бакете ic1.domain.com нет и перенаправит пользователя на указанный Вами путь, который конкатенируется из HostName + ReplaceKeyPrefixWith:domain.com/s3/thumb/miniatura.jpg
На сервере отлавливаем через роутер или .htaccess файл запрос, создаем миниатюру переданного файла, отправляем ее на Amazon S3 в нужный бакет и отображаем миниатюру первому пользователю.
Остальные пользователи – будут получать ее непосредственно с Amazon S3.
Поехали дальше.
До сих пор непонятно как именно передавать параметры для минимизации и ссылку на саму картинку.
Что имеем:
- Img_url: blablabla.com/photo15.jpg
- Thumb_w: 100
- Thumb_h: 100
Разумеется, что ссылка вида: ic1.domain.com/?Img_url=http://blablabla.com/photo15.jpg&Thumb_w=100&Thumb_h=100
нас абсолютно не устраивает, т.к. во-первых Amazon нас не поймет, а во-вторых – нет никакой защиты от вредителей.
Вариантов, как создавать такие ссылки может быть миллион. Мы решили обойтись без промежуточных таблиц или записей и посмотрели в сторону RC4 криптования. Звучит страшно. Но давайте посмотрим, что получилось:
http://ic2.domain.com/e2/PUuxR1p~D~Jgl5PrnPMLh4OA0sO899rjZgzgWFU_.jpg
Довольно таки милая ссылка. По крайней мере не намного страшнее чем md5 хеш. Зато намного информативнее. Если расшифровать крипт, получим:
blablabla.com/photo15:100@100
То что нам надо – все данные по фотографии, размеры и плюс ко всему, не зная пароля от крипта – никто не сможет нагенерить «лишних миниатюр»
Вопрос остался за малым – реализовать функцию, которая будет принимать ссылку на изображение, размеры и возвращать ссылку на миниатюру (ну и разумеется все остальные скрипты).
По ссылке на github некоторая реализация поставленной задачи: github.com/wolflingorg/s3thumb
Структура:
CS3Thumb.php – основной класс
S3.php – класс для работы с Amazon S3
CRC4Crypt.php – класс для криптования в RC4
CThumb.php – класс для создания миниатюр
Как использовать:
$Thumb = new CS3Thumb($backets, $accessKey, $secretKey, $cryptpsw = 'password');
Где:
$backets — массив с наименованиями бакетов (они же поддомены)
$accessKey и $secretKey – доступы к амазону
$cryptpsw – пароль для криптования ссылок
Для того, чтобы получить ссылку на изображение, используем:
$Thumb -> url("http://blablabla.com/photo15.jpg", 100, 100);
Для того чтобы создать миниатюру, переместить ее на S3 и отобразить первому пользователю:
$Thumb -> process("e2/PUuxR1p~D~Jgl5PrnPMLh4OA0sO899rjZgzgWFU_.jpg");
, где e2/PUuxR1p~D~Jgl5PrnPMLh4OA0sO899rjZgzgWFU_.jpg — то, что будет в ссылке после domain.com/s3/thumbs/(*), после редиректа с Amazon
Надеюсь, статья будет полезна. Спасибо.
Source: http://habrahabr.ru/post/189504/