0

我有一个脚本可以创建较大图像的缩略图,它工作正常,问题是它被放置在页面的开头,可以查看两个图像,据我了解,每次有人访问该页面时都会运行。这似乎不是很高效。

我宁愿脚本有自己的页面,并以某种方式检测到何时将更多大图像添加到它扫描的目录并开始工作。

我将如何进行设置或以某种方式改进它?

找到了这个,不知道它是如何工作的。什么是 $cmd:

  /*I combined several efforts in this topic into one function: 
This will execute $cmd in the background (no cmd window) 
without PHP waiting for it to finish, on both Windows and Unix.*/
    function execInBackground($cmd) { 
        if (substr(php_uname(), 0, 7) == "Windows"){ 
            pclose(popen("start /B ". $cmd, "r"));  
        } 
        else { 
            exec($cmd . " > /dev/null &");   
        } 
    } 
4

3 回答 3

4

时基创建:也许(如果您有 shell 访问权限),您可以创建一个“Cron 作业”:

在 ''/etc/crond.d/'' 创建一个像这样的文件:

0 6-18 * * *    root    /path/to/your/script.php >> /dev/null 2>&1

它将从 6.00 到 18.00 每小时执行一次。

有关详细信息,请参阅:http ://en.wikipedia.org/wiki/Cron。

自动创建: 如果您有“上传程序”,只需在上传后输入“缩略图生成器”即可。

挂钩创建: 确实,这取决于您在目录中添加新图像的过程。

也许,您也可以在更新目录后制作一个挂钩来执行脚本。

但是我认为第一个基于时间(cron)的解决方案是最容易实现的。

于 2012-06-05T10:41:56.420 回答
1

您可以通过多种方式做到这一点。

恕我直言,最好的方法是将脚本分解为“目录扫描”部分,通过比较源的时间戳和目标的存在和时间戳来决定哪些图像需要缩略图。

第二部分一次只缩略图一个图像。

然后,您可以运行脚本的第二部分,并仅在请求缩略图时对图像进行缩略图:

<?php
    ...
    $run = true;
    if (file_exists($thumbnail))
        if (filemtime($thumbnail) > filemtime($source))
            $run = false;
    if ($run)
    {
        // run, say, ImageMagick and convert $source to $thumbnail

        if (!$success)
            $thumbnail = './images/sorry-error-in-thumbnailing.jpg';
    }
    Header("Content-Type: image/jpeg");
    Header("Content-Length: " . filesize($thumbnail));
    readfile($thumbnail);
?>

当然,如果您不得不一次生成大量缩略图,这是很危险的,因为您可能会运行大量缩略图副本,从而占用您的服务器 CPU。

Let me clarify: you put the above script in place of IMG SRC="thumbnail1234.jpg"
request. Then the user viewing the page with the thumbnails will start several
requests for thumbnail.php?source=image123, ...?source=image235 and so on. They
will run in parallel, and most of them (if the thumb is there) can read the thumbnail
or issue a 302 Redirect to it, both very fast and with little server load.
ONLY IF the thumbnail isn't there, THAT image will appear after a delay because it
is generated and served directly. The user will see most, maybe all, images loading
instantly, and some of them lag behind a little (ideally).

在这种情况下,您可以在弹出之前运行系统负载检查,或者您可以保留正在运行的进程的运行帐户。

您可以通过检查“tempthumbnail.jpg”是否存在并且不超过 $SECONDS 秒来限制一次运行一个缩略图,将 $source 缩略图到 tempthumbnail.jpg,然后将 tempthumbnail 重命名为 $thumbnail;和/或如果系统允许可靠地使用flock()。或者您可以存储在数据库中运行的进程数:

query("UPDATE sysvars SET runner = runner + 1;");
shell_exec("...");
query("UPDATE sysvars SET runner = runner - 1;");

否则,您可以不时地运行脚本,通过 cron 或在脚本的开头,当您看到上一次运行超过 $TIME 秒之前。或者,您可以在上传要翻阅的图像时检查标志(或源目录的 filemtime())。

在后一种情况下,如果您可以控制上传,请在上传完成后立即运行缩略图。用户的上传将序列化您的翻阅过程,并且无论为“显示”新图像所做的任何操作都不太可能在上传后很快被激活;因此,当用户说“好的,激活图像 12345”时,很有可能相反,12345 的缩略图已经完成并准备“立即”显示。

很大程度上取决于翻阅脚本的运行方式。如果它总是重新生成所有缩略图,则效率低下。如果它检查,那么“试运行”只是读取整个目录和一堆 stat() 调用,这些调用非常快。除非您在数千张图像上运行,否则您无需担心。

于 2012-07-01T12:19:24.567 回答
1

如另一个答案所述,cron 将是您最好的选择,但它仅在 Linux 上可用(也许 Windows 有另一种选择)。但是,如果您需要独立于平台的解决方案,或者您无法访问服务器的配置,您可以坚持使用原始解决方案(在每次页面加载时生成缩略图),但使用 CronExpression 类对其进行修改以提高效率:https:// github.com/mtdowling/cron-expression

使用此类,您只需定义一个 cron 执行表达式,如下所示:

0 6-18 * * *

然后检查是否应该执行缩略图重新生成任务:

$cron_expression = Cron\CronExpression::factory($cron_schedule);
$next_run_date = $cron_expression->getNextRunDate();
if ($next_run_date <= new DateTime()) {
    //execute task
}
于 2012-06-28T12:28:48.077 回答