4

我找不到简洁的方式来总结标题中的问题,请允许我详细说明:

我有一个使用 PHP 脚本“getImg.php”的网站,该脚本从我的数据库中获取图像二进制对象,并在单独页面上的 HTML img 标记调用时显示它。

我想记录人们查看图像的次数,所以我添加了一个简单的行来增加适当图像的“视图”属性。

我认为这很简单,但事实证明它增加了两次。我解决这个问题的方法是使“视图”列浮动并增加 0.5 以增加 1。但是,我今天查看了我的数据库,在一些图像中找到了 0.5!

当我注释掉最后的打印时,它可以正常工作。我假设来自 HTML 标记的调用加上脚本本身算作两次调用?但其他人似乎并非如此。

这只是我的设置吗?

<?php

# Connect to db
include('db.php');

# Get ID
$id = $_GET['id'];
if(!is_numeric($id)) exit;

$q = $db->prepare("SELECT tNail,image,format FROM gallery WHERE id = '$id'");
$q->execute();
$row = $q->fetch(PDO::FETCH_ASSOC);

if(array_key_exists("thumb", $_GET))
    $img = base64_decode($row["tNail"]);
else
{
    $img = base64_decode($row["image"]);

    # Add to views if not thumb
    // 0.5 because script called twice due to print?
    $db->query("UPDATE gallery SET views = (views + 0.5) WHERE id = '$id'");
}

switch($row["format"])
{
    case ".jpg":
        header("Content-type: image/jpeg");
        break;
    case ".png":
        header("Content-type: image/png");
        break;
}

print $img;

?>

谢谢你的帮助。

4

2 回答 2

3

这似乎是一个浏览器问题。像 Chrome 这样的浏览器可以预取图像,因此它会被加载一次,如果用户点击图像的链接 - 它会被加载两次。

检查

Load a image with your browser and then check your apache access.log and if you see 2 request at the same time it is a browser issue.

于 2012-08-03T14:00:35.613 回答
2

这是你的问题:

if(array_key_exists("thumb", $_GET))
    $img = base64_decode($row["tNail"]);
else
{$img = base64_decode($row["image"]);//<==

您将此if...else分支作为 1 行交易开始,但在 else 情况下,您正在执行代码块。php 开始执行 if 下面的 1 行,跳过 else 和后续的第一行,并继续执行,就好像关闭 barcket 不存在一样。我认为这是一个错误。我最近听到很多人抱怨这件事。(从 5.3.7 或其他版本开始)。将您的ini设置为E_STRICT错误报告并检查是否有任何不同


看起来 Besnik 在我开始研究它之前就找到了它(做得好,+1)。@Lee:这是避免此问题的方法:

RewriteEngine On
SetEnvIfNoCase X-Forwarded-For .+ proxy=yes
SetEnvIfNoCase X-moz prefetch no_access=yes

# block pre-fetch requests with X-moz headers
RewriteCond %{ENV:no_access} yes
RewriteRule .* - [F,L]

在这里找到这个


if(array_key_exists("thumb", $_GET))
{
    $img = base64_decode($row["tNail"]);
}
else
{
    $img = base64_decode($row["image"]);
    $db->query("UPDATE gallery SET views = (views + 0.5) WHERE id = '$id'");
}

如果其中一个分支缺少可能导致问题的花括号。同样:如果 if 语句不包含在代码块中,则只有 else 语句之后的第一个语句(直到第一个分号的所有代码)将被解释为分支。在您的情况下,这是对$img变量的赋值。在这两种情况下都会调用数据库插入。

您可以使用以下命令检查天气或是否执行 db 查询__halt_compiler

if(array_key_exists("thumb", $_GET))
{
    $img = base64_decode($row["tNail"]);
}
else
{
    $img = base64_decode($row["image"]);
    if ($db->query("UPDATE gallery SET views = (views + 0.5) WHERE id = '$id'"))
    {
        if (array_key_exists("thumb", $_GET))
        {//this should be an impossible branch
            __halt_compiler();//or exit || throw if this is a (member) function
        }
    }
}

__halt_compiler()函数不能在除全局命名空间之外的任何其他范围内使用,并且仅影响当前正在执行的脚本,如果此脚本是包含的-例如- the index.php,则 index.php 将按原样进行,但包含脚本将停止。阅读文档以获得更全面的解释(我不擅长解释事情)。


所有这一切都不会帮助您在解决这个问题时避免这个问题,所以我建议暂时解决这个问题:

if(array_key_exists("thumb", $_GET))
{
    $img = base64_decode($row["tNail"]);
    $db = null;//disconnect
}
else
{
    $img = base64_decode($row["image"]);
    if ($db !== null)
    {//or $db instanceof PDO (or whatever object you're using)
     //or try{$db->query('UPDATE...');}catch(Exception $e){}//<- suppress exception
        $db->query("UPDATE gallery SET views = (views + 0.5) WHERE id = '$id'");
    }
}

让我知道以上哪些方法有效,或者您是否仍然遇到同样的问题。我发现这是一个非常好奇且因此很有趣的案例 :)

于 2012-08-03T13:49:22.893 回答