Я хочу отслеживать, как часто загружаются некоторые внешние изображения. Поэтому моя идея заключается не в том, чтобы дать uri прямо так:
www.site.com/image1.jpg
Я могу создать PHP-скрипт, который читает изображение, поэтому я создал PHP-файл, и мой HTML-код будет выглядеть так:
<img src="www.site.com/serveImage.php?img=image1.jpg">
но я не знаю, как читать изображение с диска и возвращать его. Будет ли я возвращать массив байтов или задавать тип содержимого?
С уважением, Мишель
Вы должны установить тип содержимого:
header("Content-type: image/jpeg");
Затем вы загружаете изображение и выводите его следующим образом:
$image=imagecreatefromjpeg($_GET['img']); imagejpeg($image);
Отправка изображений через скрипт хороша для других вещей, таких как изменение размера и кэширование по требованию.
Как ответил Паскаль МАРТИН, функция readfile
и эти заголовки являются требованиями:
header('Content-Type: image/gif');
mime_content_type
image/gif
image/jpeg
image/png
Но помимо очевидного типа контента вы также должны посмотреть на другие заголовки, такие как:
header('Content-Length: 348');
filesize
header('Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT');
filemtime
и date
для ее форматирования в требуемом формате RFC 2822
header('Last-Modified: '.date(DATE_RFC2822, filemtime($filename)));
header("HTTP/1.1 304 Not Modified");
Для последнего измененного времени найдите это в $_SERVER
If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
$_SERVER
с ключом http_if_modified_since
Список ответов HTTP-заголовков
Чтобы добиться чего-то подобного, ваш скрипт должен будет:
Это делается с помощью функции header
с некоторым кодом:
header("Content-type: image/gif");
Или
header("Content-type: image/jpeg");
или что-то еще, в зависимости от типа изображения.
Чтобы отправить данные изображения, вы можете использовать функцию readfile
:
Читает файл и записывает его в выходной буфер.
Таким образом, в одной функции вы оба читаете файл и выводите его содержимое.
В качестве опоры:
serveImage.php?file=/etc/passwd
должен быть в порядке. Я использую функцию «passthru» для вызова команды «cat», например:
header('Content-type: image/jpeg'); passthru('cat /path/to/image/file.jpg');
Работает на Linux. Экономит ресурсы.
Вместо того, чтобы изменять URL-адрес прямого изображения в HTML, вы можете поместить строку в конфигурацию Apache или .htaccess
чтобы переписать все запросы изображений в каталоге на php-скрипт. Затем в этом скрипте вы можете использовать заголовки запросов и массив $_server
для обработки запроса и обслуживания файла.
Сначала в вашем .htaccess:
RewriteRule ^(.*)\.jpg$ serve.php [NC] RewriteRule ^(.*)\.jpeg$ serve.php [NC] RewriteRule ^(.*)\.png$ serve.php [NC] RewriteRule ^(.*)\.gif$ serve.php [NC] RewriteRule ^(.*)\.bmp$ serve.php [NC]
Скрипт serve.php
должен находиться в том же каталоге, что и .htaccess
. Вы, вероятно, напишете что-то вроде этого:
<?php $filepath=$_SERVER['REQUEST_URI']; $filepath='.'.$filepath; if (file_exists($filepath)) { touch($filepath,filemtime($filepath),time()); // this will just record the time of access in file inode. you can write your own code to do whatever $path_parts=pathinfo($filepath); switch(strtolower($path_parts['extension'])) { case "gif": header("Content-type: image/gif"); break; case "jpg": case "jpeg": header("Content-type: image/jpeg"); break; case "png": header("Content-type: image/png"); break; case "bmp": header("Content-type: image/bmp"); break; } header("Accept-Ranges: bytes"); header('Content-Length: ' . filesize($filepath)); header("Last-Modified: Fri, 03 Mar 2004 06:32:31 GMT"); readfile($filepath); } else { header( "HTTP/1.0 404 Not Found"); header("Content-type: image/jpeg"); header('Content-Length: ' . filesize("404_files.jpg")); header("Accept-Ranges: bytes"); header("Last-Modified: Fri, 03 Mar 2004 06:32:31 GMT"); readfile("404_files.jpg"); } /* By Samer Mhana www.dorar-aliraq.net */ ?>
(Этот скрипт можно улучшить!)
Вероятно, вам лучше изучить журналы доступа к серверу для этого. Запуск всех изображений через php может привести к загрузке вашего сервера.
Кроме того, если вы хотите, чтобы пользователь увидел реальное имя файла вместо вашего имени сценария, когда пользовательский RMC на изображении и выбирает «Сохранить как», вам также необходимо установить этот заголовок:
header('Content-Disposition: filename=$filename');
Я также обслуживаю свои изображения с помощью файла readfile, но я прошел лишнюю милю как для обеспечения безопасности, так и для дополнительной функциональности.
У меня есть база данных, которая хранит идентификатор изображения, его размеры и расширение файла. Это также означает, что изображения нужно загружать (разрешая дополнительное изменение размера), поэтому я использую только систему для контента, а не изображения, необходимые для самого веб-сайта (например, фоны или спрайты).
Он также очень хорошо работает, чтобы убедиться, что вы можете запросить только изображения.
Таким образом, для обслуживания упрощенного рабочего процесса было бы так (не может размещать здесь производственный код):
1) получить идентификатор запрашиваемого изображения
2) Посмотрите его в базе данных
3) Выбросить заголовки на основе расширения («jpg» переназначается на «jpeg» при загрузке)
4) readfile("/images/$id.$extension");
5) Необязательно, защищать / images / dir, чтобы он не мог быть проиндексирован (не проблема в моей собственной системе, так как он сопоставляет URLS, например / image / view / 11, с чем-то вроде /index.php?module=image&action=view&id=11 )