【问题标题】:PHP to return 1x1 transparent GIF, how is this data encoded?PHP 返回 1x1 透明 GIF,这个数据是如何编码的?
【发布时间】:2011-08-10 22:52:44
【问题描述】:

我看过这个web beacon image here

代码如下:

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 转换为这种格式?

谢谢。

【问题讨论】:

  • 在任何十六进制查看器中打开您的 gif 并将其逐字节复制

标签: php image header http-headers


【解决方案1】:

比这样做更好,在设置 cookie 或添加日志条目后,您可以将调用重定向到实际图像(无论是 gif/jpeg/等),让网络服务器担心发送内容等:

header("Location: http://webserver.com/images/beacon.gif");

【讨论】:

  • 如果像素用于页面计数,则需要堆更多的缓存控制标头。
  • 同意——尽管他的问题不是关于它看起来而是关于如何返回图像。
  • 这会发出额外的完整 HTTP 请求来获取文件,这会占用网络和 Web 服务器资源。如果有很多其他资源(如 JS 和样式表)由于浏览器对同时 TCP 连接的限制而无法获取,那就更糟糕了。在这种情况下,这些资源将不得不通过网络等待额外的往返时间。
  • 但是,它将实际像素内容的缓存卸载到网络服务器上!因此,如果您在实际像素调用中正确设置标头以使其不会被缓存,那么您可以允许图像调用本身允许缓存字节——在这种情况下,实际上只会执行一个 HTTP HEAD。
  • 是的,所以如果您在图像文件上设置过期标头(因此它将在未来过期),此解决方案可能是最好的。另一种方法可能是使用我的解决方案并读取 Web 浏览器发送的 If-Modified-Since 标头(在这种情况下,我们的两个解决方案都将产生相同的结果并具有相似的性能)。
【解决方案2】:

你为什么不把图像放在一个文件中,让 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);
?>

【讨论】:

  • 如果你打算走这条路,那么在每个请求上读取文件肯定不是最佳选择(想想所涉及的磁盘访问!)。在这种情况下,我建议在第一次请求时读取此图像并将其缓存在内存中以供后续请求使用,这样您就不必每次都去磁盘
  • Liv,文件会被操作系统内核缓存在内存中。没有必要重新发明缓存。实际上,使用 readfile 运行我的第一个解决方案可能比创建一个多次调用 chr() 的文件(上下文切换!)更快。
  • 虽然这是真的,但您高估了 os 文件缓存。现实情况是 fopen() 仍将执行,内核将为文件准备所有内部结构,因此仍然会发生磁盘访问。只有在 fread 时,操作系统缓存才会启动并从内存中返回数据。再次 fclose 将需要磁盘访问(上次访问的时间戳!)
  • 您可能是正确的,但我不明白为什么这与您的解决方案有任何不同。此外,所有理智的系统管理员都禁用了 atime。
猜你喜欢
  • 2015-03-26
  • 2012-06-12
  • 2011-02-19
  • 1970-01-01
  • 2015-05-12
  • 1970-01-01
  • 2021-03-18
  • 1970-01-01
  • 2020-01-24
相关资源
最近更新 更多