PHP + Imagick = 脚本标题过早结束?

发布于 2024-11-01 05:42:21 字数 3318 浏览 3 评论 0原文

我的图像目录中有以下 .htaccess 文件:

RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*)\.jpg /images/image.php?%{REQUEST_FILENAME}

以及处理请求的脚本:

<?php
/*
 * Watermark module
 * Uses ImageMagick lib
 * 
 */

// The name of the watermark image. Should be in the same directory
// as the image.php
define('WATERMARK_IMAGE', 'watermark.png');

// Watermark images with larger width than this value (pixel)
// Set to 0 (Zero) to watermark all images
define('WATERMARK_THRESHOLD_WIDTH', 218);

$filename = $_SERVER['QUERY_STRING'];


// If the requested file doesn't exist, return HTTP 404
// Should not happen, as the htaccess handles that
if (file_exists($filename))
{
    // Get the last modified property of the source file for caching
    $file_last_modified = filemtime($filename);
    // Expirese in two months
    $expires = time() + (60 * 24 * 60 * 60);

    // Checking last modified date, if it's the same, then return 304 "Not Modified"
    // No body response is generated.
    if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) 
        && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $file_last_modified)
    {
        header("HTTP/1.1 304 Not Modified");
    }
    else
    {
        $requested_image = new Imagick($filename);

        // If the marker image doesn't exist, then return the original image
        if (file_exists(WATERMARK_IMAGE))
        {

            $watermark = new Imagick(WATERMARK_IMAGE);

            // Get original image's dimensions
            $requested_image_width = $requested_image->getImageWidth();
            $requested_image_height = $requested_image->getImageHeight();

            // Get watermark image's dimensions
            $watermark_width = $watermark->getImageWidth();
            $watermark_height = $watermark->getImageHeight();

            // Calculate watermark position
            // Current position: center - center
            $position_x = ($requested_image_width - $watermark_width)/2;
            $position_y = ($requested_image_height - $watermark_height)/2;

            // Only watermark images larger than the threshold
            if ($requested_image_width > WATERMARK_THRESHOLD_WIDTH)
            {
                $requested_image->compositeImage($watermark, imagick::COMPOSITE_OVERLAY, $position_x, $position_y);
            }

            // Destroy the marker image
            $watermark->destroy();
        }

        // Set the headers
        header("Pragma: public");
        header("Content-type: image/jpeg");
        header("Expires: " . gmdate("D, d M Y H:i:s", $expires) . " GMT");
        header("Last-Modified: " . gmdate("D, d M Y H:i:s", $file_last_modified) . " GMT");

        // Return the response image
        echo $requested_image;

        // Destroy the temporary image
        $requested_image->destroy();
    }
}
else
{
    header('HTTP/1.1 404 Not Found');
}

/* End of file image.php */
/* Location: ./images/image.php */

我的站点正在 Apache Web 服务器上运行,最近它生成以下内容:

该站点锁定,我无法加载任何内容页 5-8 分钟。有时它会生成错误 500 或错误 503,有时则不会。错误日志在有问题的时间段中包含“脚本标头提前结束”行。

这种情况每 3-4 天发生一次,但一天中的时间有所不同,它发生在周日早上和工作日下午。

我真诚的问题是: 此代码中是否存在可能导致我的问题的严重问题/缺陷/漏洞? (我没有任何理由认为问题是由脚本引起的,没有证据,但我很绝望,没有想法。)

I have the following .htaccess file in my images directory:

RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*)\.jpg /images/image.php?%{REQUEST_FILENAME}

And the script, that processes the request:

<?php
/*
 * Watermark module
 * Uses ImageMagick lib
 * 
 */

// The name of the watermark image. Should be in the same directory
// as the image.php
define('WATERMARK_IMAGE', 'watermark.png');

// Watermark images with larger width than this value (pixel)
// Set to 0 (Zero) to watermark all images
define('WATERMARK_THRESHOLD_WIDTH', 218);

$filename = $_SERVER['QUERY_STRING'];


// If the requested file doesn't exist, return HTTP 404
// Should not happen, as the htaccess handles that
if (file_exists($filename))
{
    // Get the last modified property of the source file for caching
    $file_last_modified = filemtime($filename);
    // Expirese in two months
    $expires = time() + (60 * 24 * 60 * 60);

    // Checking last modified date, if it's the same, then return 304 "Not Modified"
    // No body response is generated.
    if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) 
        && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $file_last_modified)
    {
        header("HTTP/1.1 304 Not Modified");
    }
    else
    {
        $requested_image = new Imagick($filename);

        // If the marker image doesn't exist, then return the original image
        if (file_exists(WATERMARK_IMAGE))
        {

            $watermark = new Imagick(WATERMARK_IMAGE);

            // Get original image's dimensions
            $requested_image_width = $requested_image->getImageWidth();
            $requested_image_height = $requested_image->getImageHeight();

            // Get watermark image's dimensions
            $watermark_width = $watermark->getImageWidth();
            $watermark_height = $watermark->getImageHeight();

            // Calculate watermark position
            // Current position: center - center
            $position_x = ($requested_image_width - $watermark_width)/2;
            $position_y = ($requested_image_height - $watermark_height)/2;

            // Only watermark images larger than the threshold
            if ($requested_image_width > WATERMARK_THRESHOLD_WIDTH)
            {
                $requested_image->compositeImage($watermark, imagick::COMPOSITE_OVERLAY, $position_x, $position_y);
            }

            // Destroy the marker image
            $watermark->destroy();
        }

        // Set the headers
        header("Pragma: public");
        header("Content-type: image/jpeg");
        header("Expires: " . gmdate("D, d M Y H:i:s", $expires) . " GMT");
        header("Last-Modified: " . gmdate("D, d M Y H:i:s", $file_last_modified) . " GMT");

        // Return the response image
        echo $requested_image;

        // Destroy the temporary image
        $requested_image->destroy();
    }
}
else
{
    header('HTTP/1.1 404 Not Found');
}

/* End of file image.php */
/* Location: ./images/image.php */

My site is running on an Apache web server and lately it produces the following:

The site locks up, I'm not able to load any pages for 5-8 minutes. Sometimes it generates Error 500 or Error 503, sometimes not. The error log contains "Premature end of script headers" lines in the problematic time periods.

This happens once like every 3-4 days, the time of the day varies though, it happened on sunday morning and on weekday afternoon too.

My sincere question is:
Is there a serious problem / flaw / hole in this code that can cause my problems? (I don't have any reason to think that the problem is caused by the script, no evidence, but I'm desperate and out of ideas.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文