我正在建立一个基本的分析服务,理论上基于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脚本,而不是解析日志,这样最终用户的浏览器就不会挂起或抛出错误。我的问题是,我如何在脚本的范围内最好地服务于该图像?
答案 0 :(得分:39)
也许
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')));
答案 1 :(得分:1)
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为图像提供服务,记录访问权限并将其解析。
答案 2 :(得分:1)
使用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')
答案 3 :(得分:0)
为什么不直接重定向到静态图像,而不是动态生成/输出图像?
<?php
// process query param stuff
header('Location: pixel.gif');
exit();
?>