I couldn't find a succinct way to summarise the question in the title, allow me to elaborate:
我找不到简洁的方法来总结标题中的问题,请允许我详细说明:
I have a website that uses a PHP script "getImg.php" that takes an image binary object from my database and display it when called by the HTML img tag on a separate page.
我有一个使用PHP脚本“getImg.php”的网站,该脚本从我的数据库中获取图像二进制对象,并在单独页面上的HTML img标记调用时显示它。
I would like to log the number of times people view images so I added a simple line to increment the 'views' property for the appropriate image.
我想记录人们查看图像的次数,因此我添加了一个简单的行来增加适当图像的“views”属性。
I thought this would be simple, but it turns out that it increments twice. My bodgy way around this was to make the 'views' column a float and increment by 0.5 to result with a 1 increment. However, I viewed my database today to find 0.5 in some images!
我认为这很简单,但事实证明它增加了两倍。我的方法是将“视图”列设为浮点数并增加0.5,结果为1。但是,我今天查看了我的数据库,在某些图像中找到了0.5!
When I comment out the end print it works properly. I assumed the call from the HTML tag plus the script itself counts for two calls? But this doesn't seem to be the case with other people.
当我注释掉最终打印时,它可以正常工作。我假设来自HTML标签的调用加上脚本本身计入两次调用?但其他人似乎并非如此。
Is this just my set up?
这只是我的设置吗?
<?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;
?>
Thanks for any help.
谢谢你的帮助。
2 个解决方案
#1
3
This seems to be a brwoser issue. Browsers like Chrome could prefetch the images so it is loaded once and if the user clicks on a link to a image - it is loaded twice.
这似乎是一个更加粗糙的问题。像Chrome这样的浏览器可以预取图像,使其加载一次,如果用户点击指向图像的链接,则会加载两次。
Check:
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.
使用浏览器加载图像,然后检查apache access.log,如果同时看到2个请求则是浏览器问题。
#2
2
Here's your problem:
这是你的问题:
if(array_key_exists("thumb", $_GET))
$img = base64_decode($row["tNail"]);
else
{$img = base64_decode($row["image"]);//<==
You're starting this if...else
branch as a 1-line deal, but in the else case you're executing a code block. php starts executes that 1 line below if, skips else and the first subsequent line and carries on as if the closing barcket weren't there. It's somewhat of a bug I reckon. I've been hearing a lot of people complaining about this lately. (since 5.3.7 or something). Set your ini to E_STRICT
error reporting and check if that makes any difference
如果... else分支作为1行交易,你就开始这个,但在其他情况下你正在执行代码块。 php开始执行下面的1行if,跳过else和第一个后续行并继续进行,好像关闭barcket不在那里。这有点像我估计的错误。我听到很多人最近抱怨这个。 (自5.3.7起)。将您的ini设置为E_STRICT错误报告,并检查是否有任何区别
Looks like Besnik found it before I started to even look into it (well done and +1). @Lee: Here's how to avoid this issue:
看起来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]
Found this here
在这里找到了
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 either of the branches are missing curly braces that could cause issues. Again: if the if statement isn't contained in a code block, only the first statement (all code up to the first semi-colon) following the else statement will be interpreted as a branch. This is the assignment to the $img
variable in your case. The database insert will be called in both cases.
如果任何一个分支缺少可能导致问题的花括号。同样:如果if语句未包含在代码块中,则只有else语句后面的第一个语句(直到第一个分号的所有代码)才会被解释为分支。这是你的案例中$ img变量的赋值。在这两种情况下都将调用数据库插入。
You could check to see weather or not the db query is executed using the __halt_compiler
:
你可以检查天气是否使用__halt_compiler执行db查询:
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
}
}
}
the __halt_compiler()
function cannot be used in any other scope but the global namespace, and only affects the current script being executed, if this script is an include of -for example- the index.php
, the index.php will carry on as is, but the include script will halt. Read the docs for a more comprehensive explanation (I suck at explaining things).
__halt_compiler()函数不能在除全局命名空间之外的任何其他范围内使用,并且只影响正在执行的当前脚本,如果此脚本包含 - 例如index.php,则index.php将继续执行是,但包含脚本将停止。阅读文档以获得更全面的解释(我很难解释事情)。
All this won't help you avoid this issue while figuring this one out, so I'd suggest this fugly work around for now:
所有这些都无法帮助你避免这个问题同时解决这个问题,所以我建议现在这个非常好的工作:
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'");
}
}
Let me know which of the above works, or if you're still encountering the same problem. I find this a very curious and therefore interesting case :)
让我知道上面的哪些作品,或者你是否仍然遇到同样的问题。我发现这是一个非常好奇,因此有趣的情况:)
#1
3
This seems to be a brwoser issue. Browsers like Chrome could prefetch the images so it is loaded once and if the user clicks on a link to a image - it is loaded twice.
这似乎是一个更加粗糙的问题。像Chrome这样的浏览器可以预取图像,使其加载一次,如果用户点击指向图像的链接,则会加载两次。
Check:
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.
使用浏览器加载图像,然后检查apache access.log,如果同时看到2个请求则是浏览器问题。
#2
2
Here's your problem:
这是你的问题:
if(array_key_exists("thumb", $_GET))
$img = base64_decode($row["tNail"]);
else
{$img = base64_decode($row["image"]);//<==
You're starting this if...else
branch as a 1-line deal, but in the else case you're executing a code block. php starts executes that 1 line below if, skips else and the first subsequent line and carries on as if the closing barcket weren't there. It's somewhat of a bug I reckon. I've been hearing a lot of people complaining about this lately. (since 5.3.7 or something). Set your ini to E_STRICT
error reporting and check if that makes any difference
如果... else分支作为1行交易,你就开始这个,但在其他情况下你正在执行代码块。 php开始执行下面的1行if,跳过else和第一个后续行并继续进行,好像关闭barcket不在那里。这有点像我估计的错误。我听到很多人最近抱怨这个。 (自5.3.7起)。将您的ini设置为E_STRICT错误报告,并检查是否有任何区别
Looks like Besnik found it before I started to even look into it (well done and +1). @Lee: Here's how to avoid this issue:
看起来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]
Found this here
在这里找到了
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 either of the branches are missing curly braces that could cause issues. Again: if the if statement isn't contained in a code block, only the first statement (all code up to the first semi-colon) following the else statement will be interpreted as a branch. This is the assignment to the $img
variable in your case. The database insert will be called in both cases.
如果任何一个分支缺少可能导致问题的花括号。同样:如果if语句未包含在代码块中,则只有else语句后面的第一个语句(直到第一个分号的所有代码)才会被解释为分支。这是你的案例中$ img变量的赋值。在这两种情况下都将调用数据库插入。
You could check to see weather or not the db query is executed using the __halt_compiler
:
你可以检查天气是否使用__halt_compiler执行db查询:
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
}
}
}
the __halt_compiler()
function cannot be used in any other scope but the global namespace, and only affects the current script being executed, if this script is an include of -for example- the index.php
, the index.php will carry on as is, but the include script will halt. Read the docs for a more comprehensive explanation (I suck at explaining things).
__halt_compiler()函数不能在除全局命名空间之外的任何其他范围内使用,并且只影响正在执行的当前脚本,如果此脚本包含 - 例如index.php,则index.php将继续执行是,但包含脚本将停止。阅读文档以获得更全面的解释(我很难解释事情)。
All this won't help you avoid this issue while figuring this one out, so I'd suggest this fugly work around for now:
所有这些都无法帮助你避免这个问题同时解决这个问题,所以我建议现在这个非常好的工作:
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'");
}
}
Let me know which of the above works, or if you're still encountering the same problem. I find this a very curious and therefore interesting case :)
让我知道上面的哪些作品,或者你是否仍然遇到同样的问题。我发现这是一个非常好奇,因此有趣的情况:)