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

2022-08-30 19:51:02

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

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

有没有更有效的方法让我从PHP脚本中输出1x1 GIF文件?如果不是,其中哪一个最有效和最具可扩展性?

三种已确定的方法

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

编辑

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


答案 1

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

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

如果你想制作自己版本的上述十六进制字符串,也许这样你就可以改变颜色,你可以用它来生成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
   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提供图像,记录访问并离线解析。