Автоматическое перенаправление / загрузка, если изображение не существует - оптимизация - PullRequest
1 голос
/ 07 октября 2010

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

Для этого у меня есть запись в моем файле .htaccess, которая в основном внутренне перенаправляет людей с /images/image.jpg на download.php, которая проверяет, существует ли файл. Если файл существует, он подает его (код ниже), иначе он будет использовать CURL для извлечения удаленного файла, а затем перенаправить на себя header("Location: ".$_SERVER['REQUEST_URI']);, чтобы затем показать изображение.

Неэффективно ли передавать изображения в браузер таким образом? Это быстрее, чтобы позволить веб-серверу делать это естественно? Код для чтения и показа файла ниже.

$file_extension = strtolower(substr(strrchr($filename,"."),1));

header("Pragma: public");
header("Content-Type: image/jpg");
header("Content-length: ".filesize($filename));
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filename));
readfile("$filename");

Будет ли мне лучше (читай: более эффективно), НЕ использовать перенаправление htaccess, а на самом деле изменить мою страницу 404, чтобы проверить конкретные изображения 404 и затем загрузить их?

Вот .htaccess, который определяет перенаправление на download.php

^images/([0-9]+)_([a-z0-9_]+).jpg$ /download.php?id=$1

Ответы [ 4 ]

3 голосов
/ 07 октября 2010

Немного неясно, что вы подразумеваете под «перенаправлением на себя».Есть ли какая-то причина, по которой ваш download.php не может использовать CURL для захвата изображения с удаленного сервера и последующей его обработки, используя образец кода таким же образом?Зачем ему нужно перенаправлять?

Лучше не использовать движок PHP для обслуживания изображений, если этого можно избежать, поскольку Apache может сделать это гораздо эффективнее сам по себе.Вы также теряете часть поведения Apache по умолчанию, например, ваш пример кода не отправляет последние измененные заголовки и не обрабатывает etags, поэтому, если пользователь повторно посетит ту же страницу, он в конечном итоге снова загрузит изображение вместо использования кэшированной версии.

Ваш предложенный альтернативный подход будет немного лучше, поскольку, как только ваш скрипт загрузит изображение в первый раз, все последующие запросы будут обрабатываться Apache напрямую.Просто убедитесь, что вы не отправляете 404 заголовка вместе с изображением.

В качестве альтернативы можно проверить, существуют ли файлы с помощью htaccess, так что вы можете только перенаправить запросы на несуществующие изображения в download.php и не иметьизменить свой 404 скрипт.Примерно так (не проверено):

RewriteEngine On
RewriteCond %{REQUEST_URI} ^/images
RewriteCond %{REQUEST_FILENAME} !-s
RewriteRule ^.*$ download.php [NC,L]

это означает, что если REQUEST_URI начинается с / images, а имя файла не соответствует существующему файлу в файловой системе, перепишите его в файл download.php.

Я бы также порекомендовал изучить X-Sendfile, модуль Apache, который позволяет очень легко обслуживать изображения (и другие двоичные данные).Использовать его в PHP так же просто, как отправить заголовок, содержащий путь к файлу:

header("X-Sendfile: /home/whatever/public/images/something.jpg");

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

1 голос
/ 07 октября 2010

Тебе лучше всего с префиксом переписать:

RewriteCOnd %{REQUEST_FILENAME} !-f

... и если вы загружаете файл в download.php, почему бы просто не показать его пользователю? Нет необходимости для перенаправления.

0 голосов
/ 07 октября 2010

Что касается соединения между клиентом и браузером, то это так же быстро, как и обычная обработка данных. Apache не заботится о том, откуда взялась информация, он просто отправляет данные, которые ему передают. Если данные являются результатом чтения файла или 10-миллионной программы, подобной C ++, это всего лишь биты.

Ваш метод медленнее, когда он тянет изображение с сервера изображений. По сути это означает, что изображение отправляется дважды. Один раз с сервера изображений -> хост-сервер, затем снова с хост-сервера -> клиент. Если ваш сервер изображений и хост-сервер находятся в одной и той же локальной сети с относительно небольшим количеством узлов и очень быстрым соединением, это может быть не заметным отличием. Если сервер изображений расположен в другой сети или файл изображения очень большой, разница может быть существенной и может не стоить затрат на дисковое пространство.

0 голосов
/ 07 октября 2010

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

...