PHP代码在某些条件下运行两次

时间:2014-06-20 06:53:36

标签: php

我遇到这个奇怪的问题,当满足某些条件时,我的PHP代码会运行两次。我的代码为JPEG图像添加了水印(在PHP中完成,以便我可以在必要时快速更改水印),并在需要时调整大小。为了加速请求,处理的图像被缓存。无论何时加载图像,我都会递增视图计数器,但是当发生以下情况时,计数器会增加2:

  • 宽度或高度在GET请求中设置
  • 设置了输出MIME类型(注释掉header()调用按预期运行脚本
  • 调用
  • imagecreatefromjpeg()并调整图像大小 - 当这些行被注释掉时,脚本会正常运行。如果未调整图像大小,脚本也会正常运行。
  • 浏览器是Firefox。 Internet Explorer 11正常运行,由我的访问日志确认。 (我还没有测试过其他浏览器。)

这是我的代码:

<?php
require_once("../config.php");
if (empty($_GET['photoid'])) {
    header("Location: /photos");
    die();
}
$photoId = intval($_GET['photoid']);
$photo = getPhotoData($photoId);
if ($photo == null) {
    http_response_code(404);
    echo "That photo doesn't exist.";
} else {
    $filename = $photo['photo_filename'];

    $largePath = "large/";
    $cachePath = $largePath . "view_cache/";
    $cache = false;

    if (!isset($_GET['admin']) && !isset($_GET['thumb']) && !isset($_GET['tile'])) {
        incrementPhotoViewCount($photoId);
    }

    if (isset($_GET['height'])) {
        list($originalWidth, $originalHeight) = getimagesize($largePath . $photo['photo_filename']);
        $height = min(intval($_GET['height']), $originalHeight);
        if (file_exists($cachePath . $height . "h" . $filename)) {
            $im = imagecreatefromjpeg($cachePath . $height . "h" . $filename);
            $cache = true;
        } else {
            $im = resizeImage($largePath . $photo['photo_filename'], $originalWidth, $height);
        }
    } else if (isset($_GET['width'])) {
        list($originalWidth, $originalHeight) = getimagesize($largePath . $photo['photo_filename']);
        $width = min(intval($_GET['width']), $originalWidth);
        if (file_exists($cachePath . $width . "w" . $filename)) {
            $im = imagecreatefromjpeg($cachePath . $width . "w" . $filename);
            $cache = true;
        } else {
            $im = resizeImage($largePath . $photo['photo_filename'], $width, $originalHeight);
        }
    } else {
        if (file_exists($cachePath . $filename)) {
            $im = imagecreatefromjpeg($cachePath . $filename);
            $cache = true;
        } else {
            $im = imagecreatefromjpeg($largePath . $photo['photo_filename']);
        }
    }

    if (!$cache && ((!isset($height) || $height > 400) && (!isset($width) || $width > 350))) {
        $watermark = imagecreatefrompng("../images/watermark.png");

        //Preserve original watermark transparency
        imagealphablending($watermark, true); // setting alpha blending on
        imagesavealpha($watermark, true); // save alphablending setting (important)

        //Set the margins for the watermark and get the height/width of the stamp image
        $marginLeft = 20;
        $marginBottom = 20;
        $sx = imagesx($watermark);
        $sy = imagesy($watermark);

        //Merge the stamp onto our photo
        imagecopy($im, $watermark, $marginLeft, imagesy($im) - $sy - $marginBottom, 0, 0, $sx, $sy);
    }

    //Output the image and free memory
    header("Content-Type: image/jpeg");
    imagejpeg($im);
    if (!$cache) {
        if (isset($_GET['height'])) {
            imagejpeg($im, $cachePath . $height . "h" . $filename);
        } else if (isset($_GET['width'])) {
            imagejpeg($im, $cachePath . $width . "w" . $filename);
        } else {
            imagejpeg($im, $cachePath . $filename);
        }
    }
    imagedestroy($im);
}

function resizeImage($file, $w, $h, $crop = false) {
    list($width, $height) = getimagesize($file);
    $r = $width / $height;
    if ($crop) {
        if ($width > $height) {
            $width = ceil($width-($width*abs($r-$w/$h)));
        } else {
            $height = ceil($height-($height*abs($r-$w/$h)));
        }
        $newwidth = $w;
        $newheight = $h;
    } else {
        if ($w/$h > $r) {
            $newwidth = $h*$r;
            $newheight = $h;
        } else {
            $newheight = $w/$r;
            $newwidth = $w;
        }
    }
    $src = imagecreatefromjpeg($file);
    $dst = imagecreatetruecolor($newwidth, $newheight);
    imagecopyresampled($dst, $src, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);

    return $dst;
}

这是更新视图计数器的代码:

function incrementPhotoViewCount($photoId) {
    $photoId = intval($photoId);

    if (!($stmt = $GLOBALS['mysqli']->prepare("UPDATE `Photo` SET `view_count` = `view_count` + 1 WHERE `photo_id` = ?"))) {
        error_log("Prepare failed: (" . $GLOBALS['mysqli']->errno . ") " . $GLOBALS['mysqli']->error);
        return false;
    }

    if (!$stmt->bind_param("i", $photoId)) {
        error_log("Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error);
        return false;
    }

    if (!$stmt->execute()) {
        echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
        return false;
    }
}

这里发生了什么?

1 个答案:

答案 0 :(得分:1)

一些额外的深夜谷歌搜索回答了我的问题 - 结果Firefox has a bug which causes it to load dynamically generated images twice when loaded directly。通过<img>标记加载时,它很好,所有其他浏览器的行为都正常。有问题的其他人可以看一下:)