最有效的方式来显示1x1 GIF(跟踪像素,网络信标)

时间:2022-11-30 15:51:56

I'm building a basic analytics service, based in theory off of how Google Analytics works, but instead of requesting an actual image, I'm routing the image request to a script that accepts the data and then outputs an image. Since browsers will be requesting this image on every load, every millisecond counts.

我正在构建一个基本的分析服务,理论上基于Google Analytics的工作原理,但我没有请求实际的图像,而是将图像请求路由到接受数据然后输出图像的脚本。由于浏览器将在每次加载时请求此图像,因此每毫秒都会计算。

I'm looking for the most efficient way for a file to output a gif file from a PHP script. So far, I've established 3 main methods.

我正在寻找一种文件从PHP脚本输出gif文件的最有效方法。到目前为止,我已经建立了3种主要方法。

Is there a more efficient way for me output a 1x1 GIF file from within a PHP script? If not, which of these is the most efficient and scalable?

我是否有更有效的方法从PHP脚本中输出1x1 GIF文件?如果没有,哪些是最有效和可扩展的?

Three Identified Methods

PHP image building libraries

PHP图像构建库

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

file_get_contents the image off of the server and output it

file_get_contents服务器的图像并输出它

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

base64_decode the image

base64_decode图像

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

(My gut was that base64 would be fastest, but I have no idea how resource intensive that function is; and that file_get_contents would likely scale less well, since it adds another file-system action.)

(我的直觉是base64会是最快的,但我不知道该函数的资源密集程度如何;而且file_get_contents可能扩展得不太好,因为它增加了另一个文件系统操作。)

For reference, the GIF I'm using is here: http://i.stack.imgur.com/LQ1CR.gif

作为参考,我使用的GIF在这里:http://i.stack.imgur.com/LQ1CR.gif

EDIT

So, the reason I'm serving this image is that my analytics library builds a query string and attaches it to this image request. Rather than parse logs, I'm routing the request to a PHP script which processes the data and responds with an image,so that the end user's browser doesn't hang or throw an error. My question is, how do I best serve that image within the confines of a script?

因此,我提供此图像的原因是我的分析库构建了一个查询字符串并将其附加到此图像请求。我将请求路由到处理数据并响应图像的PHP脚本,而不是解析日志,这样最终用户的浏览器就不会挂起或抛出错误。我的问题是,如何在脚本的范围内最好地服务于该图像?

4 个解决方案

#1


37  

maybe

也许

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";

That will output a binary string identical to the binary file contents of a 1x1 transparent gif. I'm claiming this as efficient based on the grounds that it doesn't do any slow IO such as reading a file, nor do I call any functions.

这将输出与1x1透明gif的二进制文件内容相同的二进制字符串。我声称这是有效的,因为它不会做任何缓慢的IO,如读取文件,也不会调用任何函数。

If you want to make your own version of the above hex string, perhaps so that you can change the color, you can use this to generate the php code for the echo statement.

如果你想制作你自己的上述十六进制字符串版本,也许你可以改变颜色,你可以使用它来生成echo语句的php代码。

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')));

#2


1  

   header('Content-Type: image/gif'); 
   header("Content-Length: " . filesize("image.gif"));
   $f = fopen('image.gif', 'rb');
   fpassthru($f);
   fclose($f);

Probably would be fastest for image from disk, but (especially if you're using bytecode caching) for a small images known in advance the base64 way will be the fastest I think. Sending Content-Length might be a good idea too, for the small image the browser would in most cases not wait for anything after receiving the bytes so while your server would take as much time, use experience will be sightly better.

对于来自磁盘的图像来说可能是最快的,但是(特别是如果你使用字节码缓存)对于预先知道的小图像,我认为base64方式将是最快的。发送内容长度也是一个好主意,对于小图像,浏览器在大多数情况下不会在收到字节后等待任何事情,因此当您的服务器花费尽可能多的时间时,使用体验会更好。

Another way would be to let Apache/lighttpd/nginx serve the image, log the access and the parse it offline.

另一种方法是让Apache / lighttpd / nginx为图像提供服务,记录访问权限并将其解析。

#3


0  

Instead of dynamically generating/outputting an image, why not just redirect to a static image?

而不是动态生成/输出图像,为什么不直接重定向到静态图像?

<?php
// process query param stuff

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

#4


0  

With Laravel:

与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),
]);

If anyone wants that for some reason.

如果有人想出于某种原因。

Alternatively, if you don't like long(ish) hex strings in your code:

或者,如果您不喜欢代码中的long(ish)十六进制字符串:

base64_decode('R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw')

#1


37  

maybe

也许

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";

That will output a binary string identical to the binary file contents of a 1x1 transparent gif. I'm claiming this as efficient based on the grounds that it doesn't do any slow IO such as reading a file, nor do I call any functions.

这将输出与1x1透明gif的二进制文件内容相同的二进制字符串。我声称这是有效的,因为它不会做任何缓慢的IO,如读取文件,也不会调用任何函数。

If you want to make your own version of the above hex string, perhaps so that you can change the color, you can use this to generate the php code for the echo statement.

如果你想制作你自己的上述十六进制字符串版本,也许你可以改变颜色,你可以使用它来生成echo语句的php代码。

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')));

#2


1  

   header('Content-Type: image/gif'); 
   header("Content-Length: " . filesize("image.gif"));
   $f = fopen('image.gif', 'rb');
   fpassthru($f);
   fclose($f);

Probably would be fastest for image from disk, but (especially if you're using bytecode caching) for a small images known in advance the base64 way will be the fastest I think. Sending Content-Length might be a good idea too, for the small image the browser would in most cases not wait for anything after receiving the bytes so while your server would take as much time, use experience will be sightly better.

对于来自磁盘的图像来说可能是最快的,但是(特别是如果你使用字节码缓存)对于预先知道的小图像,我认为base64方式将是最快的。发送内容长度也是一个好主意,对于小图像,浏览器在大多数情况下不会在收到字节后等待任何事情,因此当您的服务器花费尽可能多的时间时,使用体验会更好。

Another way would be to let Apache/lighttpd/nginx serve the image, log the access and the parse it offline.

另一种方法是让Apache / lighttpd / nginx为图像提供服务,记录访问权限并将其解析。

#3


0  

Instead of dynamically generating/outputting an image, why not just redirect to a static image?

而不是动态生成/输出图像,为什么不直接重定向到静态图像?

<?php
// process query param stuff

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

#4


0  

With Laravel:

与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),
]);

If anyone wants that for some reason.

如果有人想出于某种原因。

Alternatively, if you don't like long(ish) hex strings in your code:

或者,如果您不喜欢代码中的long(ish)十六进制字符串:

base64_decode('R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw')