我有一个动态的缩略图脚本,发现在网络周围放置并进行了一些调整。我添加的一件事是一种缓存机制。每当生成新的拇指时,将其保存到磁盘,如果再次请求相同的缩略图(所有相同的选项),则将使用磁盘副本。

片段:

  // name of cached file
  $thumb_file = $_SERVER['DOCUMENT_ROOT'].'/thumbs/cache/'.
                str_replace('/', '_', $_REQUEST['p']).
                ".{$def_width}x{$def_height}".
                ($clamp ? '_'.implode('x',$clamp) : '').
                ($make_png?'.png':'.jpg');

  // get it from cache if it's there
  if ($use_cache && file_exists($thumb_file)) {
    Header("Content-type: image/".($make_png?'png':'jpeg'));

    // this part seems really slow

    $fp=fopen($thumb_file, "rb");
    while (!feof($fp)) print fread($fp, 4096);

    exit();
  }

然而, print结果 fread 似乎很慢,有时(很少)图像并不能完全加载。

那么,我该如何加快速度?我应该只是将浏览器重定向到图像而不是 fread它,还是还有其他选择?

我在下面包括完整的PHP脚本,以防万一。

<?php

  $use_cache = $_REQUEST['nc'] ? false : true;
  // $use_cache = false;

  $upfile = $_SERVER['DOCUMENT_ROOT'] .'/'. $_REQUEST['p'];
  $def_width  = $_REQUEST["w"];
  $def_height = $_REQUEST["h"];
  $clamp = $_REQUEST['c'] ? explode("x",$_REQUEST['c']) : null;
  $make_png = $_REQUEST['png'];

  if (!file_exists($upfile)) {
    die();  // $upfile = "nophoto.jpg";
  }

  if (!"{$def_width}{$def_height}") {
    $def_width = $def_height = '100';
  }

  // name of cached file
  $thumb_file = $_SERVER['DOCUMENT_ROOT'].'/thumbs/cache/'.
                str_replace('/', '_', $_REQUEST['p']).
                ".{$def_width}x{$def_height}".
                ($clamp ? '_'.implode('x',$clamp) : '').
                ($make_png?'.png':'.jpg');

  // get it from cache if it's there
  if ($use_cache && file_exists($thumb_file)) {
    Header("Content-type: image/".($make_png?'png':'jpeg'));
    $fp=fopen($thumb_file, "rb");
    while (!feof($fp)) print fread($fp, 4096);
    exit();
  }

  $ext = strtolower(substr($upfile, -3));

  ini_set('memory_limit', '64M');

  if ($ext=="gif") 
    $src = @ImageCreateFromGif ($upfile);
  else if ($ext=="jpg") 
    $src = @ImageCreateFromJpeg($upfile);
  else if ($ext=="png") 
    $src = @ImageCreateFromPng($upfile);

  $size = GetImageSize($upfile); 
  $width = $size[0];
  $height = $size[1];

  $long_side = $def_width;
  if ($def_width < $def_height) $long_side = $def_height;

  if (!$def_width) {
    $factor_h = $height / $def_height;
    $def_width = $width / $factor_h;
  }
  if (!$def_height) {
    $factor_w = $width / $def_width;
    $def_height = $height / $factor_w;
  }
  $factor_w = $width / $def_width;
  $factor_h = $height / $def_height;

  if ($factor_w > $factor_h) {
    $new_height = floor($def_height * $factor_h);
    $new_width = floor($def_width  * $factor_h);
  } else {
    $new_height = floor($def_height * $factor_w);
    $new_width = floor($def_width  * $factor_w);
  }

  if ((!$clamp[0])&&$clamp[0]!=='0') $clamp[0] = 50;
  if ((!$clamp[1])&&$clamp[1]!=='0') $clamp[1] = 50;

  $src_x = ceil(($width  - $new_width)  * ($clamp[0] / 100));
  $src_y = ceil(($height - $new_height) * ($clamp[1] / 100));

  $dst = ImageCreateTrueColor($def_width, $def_height);

  @ImageCopyResampled($dst, $src, 0, 0, $src_x, $src_y, 
                      $def_width, $def_height, $new_width, $new_height);

  Header("Content-type: image/".($make_png?'png':'jpeg'));

  if ($make_png) {
    ImagePng($dst);
    if ($use_cache) { 
      ImagePng($dst, $thumb_file); 
    }
  } else {
    ImageJpeg($dst, null, 95);
    if ($use_cache) { 
      ImageJpeg($dst, $thumb_file, 95); 
    }
  }

  @ImageDestroy($src);
  @ImageDestroy($dst);

?>
有帮助吗?

解决方案

请在某些数字方面定义“看起来”和“非常缓慢”。
否则,只能以相同的术语有答案 - “看来您可以大致得到一些东西”。

任何问“我该如何加快”的人都应该首先回答这些问题:

  • 我想加快一定的操作
  • 目前需要花费一定的时间。
  • 一定的时间会适合我。

根据我自己的不完美测试,通过PHP提供图片的速度比通过Web-Server本身慢2倍。合理,我会说,不是“非常慢”。
因此,如果它运行“非常慢”,可能还有其他原因。像这种缓存机制一样,由于某些错误而根本无法正常工作。或者其他的东西。一些 分析, , 也 调试必需的 在任何人都可以提供帮助之前。

特别是对于那些会尖叫的人“这不是答案!” (由于这个愚蠢的假设,答案仅计算它是直接的,并且 积极的),这是OP的链接:
http://shiftingpixel.com/2008/03/03/smart-image-resizer/
在Fly Thumbnail创建脚本上也是如此,但“未修改” HTTP缓存实现。

其他提示

功能 readfile 应该更快。

如果您使用PHP作为Apache模块,也可以查看 virtual.

如果您的Web服务器支持它, X-Sendfile 可能有助于加快事情的速度。

移至PHP5。
PHP 4有几个错误,这些错误导致所有形式的甲状管均放慢速度和泄漏内存。根据您的描述,这听起来像您所面对的。

升级,最好至少为5.3+

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top