Самый эффективный способ отображения GIF 1x1 (пиксель отслеживания, веб-маяк) - PullRequest
20 голосов
/ 12 января 2011

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

Я ищу наиболее эффективный способ вывода файла gif из сценария PHP. Пока что я установил 3 основных метода.

Есть ли более эффективный способ вывода файла GIF 1x1 из сценария PHP? Если нет, то какой из них является наиболее эффективным и масштабируемым?

Три идентифицированных метода

Библиотеки построения изображений PHP

$im = imagecreatetruecolor(1, 1);
imagefilledrectangle($im, 0, 0, 0, 0, 0xFb6b6F);
header('Content-Type: image/gif');
imagegif($im);
imagedestroy($im);

file_get_contents изображение с сервера и вывод его

$im = file_get_contents('raw.gif'); 
header('Content-Type: image/gif'); 
echo $im; 

base64_decode изображение

header('Content-Type: image/gif');
echo base64_decode("R0lGODdhAQABAIAAAPxqbAAAACwAAAAAAQABAAACAkQBADs=");

(у меня сложилось впечатление, что base64 будет быстрее, но я понятия не имею, насколько ресурсоемкой является эта функция; и что file_get_contents, вероятно, будет масштабироваться хуже, так как добавляет еще одно действие файловой системы.)

Для справки, GIF, который я использую здесь: http://i.stack.imgur.com/LQ1CR.gif

EDIT

Итак, причина, по которой я обслуживаю это изображение, заключается в том, что моя аналитическая библиотека создает строку запроса и прикрепляет ее к этому запросу изображения. Вместо того, чтобы анализировать логи, я перенаправляю запрос в PHP-скрипт, который обрабатывает данные и отвечает изображением, чтобы браузер конечного пользователя не зависал и не выдавал ошибку. У меня вопрос: как мне лучше обслуживать это изображение в рамках сценария?

Ответы [ 4 ]

39 голосов
/ 12 января 2011

возможно

header('Content-Type: image/gif');
//equivalent to readfile('pixel.gif')
echo "\x47\x49\x46\x38\x37\x61\x1\x0\x1\x0\x80\x0\x0\xfc\x6a\x6c\x0\x0\x0\x2c\x0\x0\x0\x0\x1\x0\x1\x0\x0\x2\x2\x44\x1\x0\x3b";

Это выведет двоичную строку, идентичную содержимому двоичного файла прозрачного GIF 1x1. Я утверждаю, что это эффективно, потому что он не выполняет медленный ввод-вывод, такой как чтение файла, и не вызывает никаких функций.

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

printf('echo "%s";', preg_replace_callback('/./s', function ($matches) {
    return '\x' . dechex(ord($matches[0]));
}, file_get_contents('https://upload.wikimedia.org/wikipedia/en/d/d0/Clear.gif')));
1 голос
/ 27 января 2018

С Laravel:

$pixel = "\x47\x49\x46\x38\x39\x61\x1\x0\x1\x0\x80\x0\x0\xff\xff\xff\x0\x0\x0\x21\xf9\x4\x1\x0\x0\x0\x0\x2c\x0\x0\x0\x0\x1\x0\x1\x0\x0\x2\x2\x44\x1\x0\x3b";
return response($pixel,200,[
    'Content-Type' => 'image/gif',
    'Content-Length' => strlen($pixel),
]);

Если кто-то хочет по какой-то причине.

В качестве альтернативы, если вам не нравятся длинные (ish) шестнадцатеричные строки в вашем коде:

base64_decode('R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw')
1 голос
/ 12 января 2011
   header('Content-Type: image/gif'); 
   header("Content-Length: " . filesize("image.gif"));
   $f = fopen('image.gif', 'rb');
   fpassthru($f);
   fclose($f);

Вероятно, будет быстрее для образа с диска, но (особенно если вы используете кэширование байт-кода) для небольших заранее известных изображений способ base64 будет самым быстрым, как мне кажется.Отправка Content-Length также может быть хорошей идеей, поскольку для небольшого изображения браузер в большинстве случаев не будет ничего ждать после получения байтов, поэтому, в то время как ваш сервер займет столько же времени, опыт использования будет заметно лучше.

Другим способом было бы позволить Apache / lighttpd / nginx обслуживать образ, регистрировать доступ и анализировать его в автономном режиме.

0 голосов
/ 13 января 2011

Вместо того, чтобы динамически генерировать / выводить изображение, почему бы просто не перенаправить на статическое изображение?

<?php
// process query param stuff

header('Location: pixel.gif');
exit();
?>
...