0

When we output images via PHP with image_jpeg or file_get_contents it takes more than twice as long as when we use straight links to the jpg files.
These files are about 180kb.
With our thumbnails (4kb images) there's not much of a time difference between the link and output via PHP.

Anyone know of a why PHP output is slower with larger files and a way to fix it?

4

2 回答 2

3

我能想到的就是它在通过PHP解析时被解析了两次,而不是直接发送给客户端。因为 file_get_contents 执行它所说的,它读取内容,然后将其发送给客户端。不过我可能是错的。

于 2013-03-13T11:20:12.783 回答
0

image_jpeg 和 file_get_contents 之间存在差异。第一个是创建 jpeg 的 gd 函数,这需要时间。第二个只是从文件中读取数据。

问题是如何将其输出到浏览器。如果不采取适当的措施,内容永远不会被缓存,所以浏览器每次都要下载。静态图像总是由浏览器缓存,在第一次加载后,几乎不需要时间(只是一个 HEAD 请求)。

试试这个代码:

function CachedFileResponse($thefile,$nocache=0) {
  if (!file_exists($thefile)) {
    error_log('cache error: file not found: '.$thefile);
    header('HTTP/1.0 404 Not Found',true,404);
  } else {
    $lastmodified=gmdate('D, d M Y H:i:s \G\M\T', filemtime($thefile));
    $etag = '"'.md5($lastmodified.filesize($thefile).$thefile).'"';
    header('ETag: '.$etag);
    header('Last-Modified: '.$lastmodified);
    header('Cache-Control: max-age=3600');
    header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time()+86400));
    $ext=strtolower(substr($thefile,strrpos($thefile,'.')+1));
    $fname=substr($thefile,strrpos($thefile,'/')+1);
    if ($ext=='jpg' || $ext=='jpeg') {
      header('Content-Type: image/jpeg');
    } elseif ($ext=='gif') {
      header('Content-Type: image/gif');
    } elseif ($ext=='png') {
      header('Content-Type: image/png');
    } else {
      header('Content-Type: application/binary');
    }
    header('Content-Length: ' . filesize($thefile));
    header('Content-Disposition: filename="'.$fname.'"');

    $ifmodifiedsince = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) : false;
    $ifnonematch = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : false;
    if ($nocache || (!$ifmodifiedsince && !$ifnonematch) ||
       ($ifnonematch && $ifnonematch != $etag) ||
       ($ifmodifiedsince && $ifmodifiedsince != $lastmodified)) {
      error_log('cache miss: '.$thefile);
      $fp = fopen($thefile, 'rb');
      fpassthru($fp);
      fclose($fp);
    } else {
      error_log('cache hit: '.$thefile);
      header("HTTP/1.0 304 Not Modified",true,304);
    }
  }
}
于 2013-03-13T11:25:14.767 回答