#php #image #header #http-headers
#php #изображение #заголовок #http-заголовки
Вопрос:
Я видел это изображение веб-маяка здесь
Код выглядит следующим образом:
header( 'Content-type: image/gif' );
# The transparent, beacon image
echo chr(71).chr(73).chr(70).chr(56).chr(57).chr(97).
chr(1).chr(0).chr(1).chr(0).chr(128).chr(0).
chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).
chr(33).chr(249).chr(4).chr(1).chr(0).chr(0).
chr(0).chr(0).chr(44).chr(0).chr(0).chr(0).chr(0).
chr(1).chr(0).chr(1).chr(0).chr(0).chr(2).chr(2).
chr(68).chr(1).chr(0).chr(59);
И это очень упростило возможность PHP возвращать прозрачное GIF-изображение. Однако, если я хочу изменить изображение, как я могу это сделать? Как мне преобразовать любой GIF, который я создаю, в этот формат?
Спасибо.
Комментарии:
1. Откройте свой gif в любом шестнадцатеричном средстве просмотра и скопируйте его байт в байт
Ответ №1:
Почему бы вам просто не поместить изображение в файл и не позволить PHP прочитать и вернуть его?
header('Content-type: image/gif');
readfile('file.gif');
Если вы действительно хотите преобразовать изображение в PHP-код, считывайте его по одному байту за раз и создавайте PHP-код следующим образом:
<?php
$fh = fopen('file.gif', 'r');
$i = 0;
echo 'echo ';
while(!feof($fh)) {
$byte = fread($fh, 1);
$num = ord($byte);
echo 'chr(', $num, ')';
if(!feof($fh)) {
echo '.'; //there's more bytes, echo dot
if( $i % 6 == 0) {
echo "n "; //do not be too wide
}
}
}
echo ";n";
fclose($fh);
?>
Комментарии:
1. если вы собираетесь пойти по этому пути, то определенно не оптимально читать файл при каждом запросе (подумайте о доступе к диску!). Я бы посоветовал прочитать это изображение в этом случае при первом запросе и кэшировать его в памяти для последующих запросов, чтобы вам не приходилось каждый раз обращаться к диску
2. Лив, файл будет кэширован в оперативной памяти ядром ОС. Нет необходимости изобретать это кэширование заново. На самом деле, вероятно, быстрее запустить мое первое решение с readfile, чем создавать файл с многочисленными вызовами chr() (переключение контекста!).
3. хотя это правда, вы переоцениваете кэширование файлов операционной системы. Реальность такова, что fopen () все равно будет выполняться, и ядро подготовит все внутренние структуры для файла, поэтому доступ к диску для этого все равно произойдет. только в момент fread кэширование операционной системы сработает и вернет вам данные из памяти. для fclose снова потребуется доступ к диску (временная метка последнего обращения!)
4. Возможно, вы правы, но я не понимаю, почему это должно отличаться от вашего решения. Кроме того, atime отключен всеми здравомыслящими системными администраторами.
Ответ №2:
лучше, чем делать это, после установки cookie или добавления записи в журнале, вы можете просто перенаправить вызов на реальное изображение (будь то gif / jpeg / etc) И позволить веб-серверу беспокоиться об отправке содержимого и т. Д:
header("Location: http://webserver.com/images/beacon.gif");
Комментарии:
1. Требуется еще куча заголовков для управления кэшем, если пиксель предназначен для подсчета страниц.
2. согласен — хотя его вопрос, похоже, был не об этом, а скорее о том, как вернуть изображение.
3. Это создает дополнительный полный HTTP-запрос для получения файла, который занимает ресурсы как сети, так и веб-сервера. Особенно плохо, если есть много других ресурсов (таких как JS и таблицы стилей), которые нельзя получить из-за ограничения браузера на одновременные TCP-соединения. В этом случае этим ресурсам придется ждать дополнительное время в оба конца по сети.
4. однако это выгружает кэширование фактического содержимого пикселей на веб-сервер! итак, если вы правильно настроите свои заголовки в реальном вызове pixel, чтобы они не кэшировались, тогда вы можете разрешить сам вызов image для разрешения кэширования байтов — в этом случае на самом деле будет выполняться только HTTP HEAD.
5. Верно, поэтому это решение может быть лучшим, если вы установите заголовки expire для файла изображения (чтобы срок его действия истекал в будущем). Другим способом могло бы быть использование моего решения, а также чтение заголовков If-Modified-Since, отправляемых веб-браузером (в этом случае оба наших решения выдадут одинаковый результат и будут иметь одинаковую производительность).