SQL查询:增加2而不是1

时间:2009-07-24 21:40:56

标签: php sql debugging mysql

我正在尝试通过将其整数值增加1来更新表中的字段。这是我正在使用的内容:

function updateViews($id){

$sql = "UPDATE tweets SET tweet_views = tweet_views + 1 WHERE tweet_key = '$id'";

$result = mysql_query($sql) or die("DB Error : ". mysql_error());

return $result;

}

但是,我发现它每次递增2而不是1?我做错了什么?

由于

更新

从答案来看,SQL是正确的。你认为这可能会受到重写引擎的影响吗?我问,因为我100%确定这不会运行两次或我没有拨打电话,因为有两个脚本。一个调用函数和一个函数!这很令人困惑。

更新2

使用调试功能。我得到了这个输出:

array(4) {
  ["file"]=>
  string(35) "/home/magic/public_html/dbUpdate.php"
  ["line"]=>
  int(16)
  ["function"]=>
  string(15) "myDebugFunction"
  ["args"]=>
  array(0) {
  }
}

array(4) {
  ["file"]=>
  string(31) "/home/magic/public_html/view.php"
  ["line"]=>
  int(10)
  ["function"]=>
  string(11) "updateViews"
  ["args"]=>
  array(1) {
    [0]=>
    &string(5) "7jjdd"
  }
}

看起来好像脚本被调用了一次,但它仍然被更新两次???救命! :(

同样来自日志文件,看起来好像是三次调用脚本?

13:16:28 id:4a6c9d7cf38016.29304000
  _SERVER[REQUEST_URI]=/lucic
  _SERVER[REDIRECT_URL]=/lucic
  /home/magic/public_html/dbUpdate.php@16 :myDebugFunction
  /home/magic/public_html/view.php@10 :updateViews
13:16:30 id:4a6c9d7eaf93e3.88114161
  _SERVER[REQUEST_URI]=/lucic
  _SERVER[REDIRECT_URL]=/lucic
  /home/magic/public_html/dbUpdate.php@16 :myDebugFunction
  /home/magic/public_html/view.php@10 :updateViews
13:16:31 id:4a6c9d7f846557.12618673
  _SERVER[REQUEST_URI]=/lucic
  _SERVER[REDIRECT_URL]=/lucic
  /home/magic/public_html/dbUpdate.php@16 :myDebugFunction
  /home/magic/public_html/view.php@10 :updateViews

更新3

以下是我的htaccess文件中可能导致问题的内容。

# REWRITE DEFAULTS
RewriteEngine On
RewriteBase /

RewriteCond %{HTTP_HOST} ^www\.mysite\.com$ [NC]
RewriteRule ^(.*)$ http://mysite.com/$1 [R=301,L]

# /view.php?t=h5k6 externally to /h5k6
RewriteCond %{THE_REQUEST} ^GET\ /view\.php
RewriteCond %{QUERY_STRING} ^([^&]*&)*t=([^&]+)&?.*$
RewriteRule ^view\.php$ /%2? [L,R=301]

# /h5k6 internally to /view.php?t=h5k6
RewriteRule ^([0-9a-z]+)$ view.php?t=$1 [L]

13 个答案:

答案 0 :(得分:8)

您错误地多次运行查询。 :)

(好吧,这只是一个猜测,但我建议一些日志记录以确保)

答案 1 :(得分:6)

您可以测试您的函数是否被调用两次,或者您的脚本是否带有一些调试日志。

function myDebugFunction() {
  static $iid = null;

  if ( is_null($iid) ) {
    $iid = uniqid('', true);
  }

  $log = date('H:i:s').' id:'.$iid."\n".
    "  _SERVER[REQUEST_URI]=". @$_SERVER['REQUEST_URI']."\n" .
    "  _SERVER[REDIRECT_URL]=". @$_SERVER['REDIRECT_URL'];
  foreach(debug_backtrace() as $bt) {
    echo '<pre>'; var_dump($bt); echo '</pre>';
    $log .= "\n  ".$bt['file'].'@'.$bt['line'].' '.@$bt['class'].':'.$bt['function'];
  }
  $log .= "\n";
  error_log($log, 3, 'mydebug.log');
}

function updateViews($id) {
  myDebugFunction();
  $sql = "
    UPDATE
      tweets
    SET
      tweet_views = tweet_views + 1
    WHERE
      tweet_key = '".mysql_real_escape_string($id) ."'
  ";
  $result = mysql_query($sql) or die("DB Error : ". mysql_error());
  return $result;
}

如果在mydebug.log中找到两次相同的id,则该函数被调用两次(在同一个php实例中)。否则,您的脚本已被调用两次。

答案 2 :(得分:6)

没有涉及触发器,是吗?

答案 3 :(得分:4)

目前有一些浏览器(我认为Chrome就是其中之一)在POST到表单后错误地发出GET,这可能会解决您所看到的问题。

您是否可以将请求记录到您的php应用程序中,看看您是否从浏览器中点击了两次?

答案 4 :(得分:2)

SQL是正确的。我将跟踪PHP并确保没有对运行SQL的函数进行重复调用。

答案 5 :(得分:1)

此页面是错误处理页面吗?

REDIRECT_URL与REQUEST_URI相同的事实表明,因为在处理ErrorDocuments或类似事件时,REDIRECT_URL似乎是由apache设置的变量。

鉴于该文件似乎确实多次运行,可能会出现一些重定向循环 - 你的.htaccess文件中有什么内容?

编辑:这里有更多信息:http://onlamp.com/pub/a/onlamp/2003/02/13/davidsklar.html?page=last

答案 6 :(得分:1)

您可能希望在此处包含结果页面的HTML。它可能是脚本,链接(css)或img标签格式不正确,只是通过“”,“#”或“?”进入重写。因为那些将“解析”到同一个网址。如果你不是绝对路径所有的网址(images / header.gif而不是/images/header.gif等),其中一些可能会失败,特别是因为浏览器这些短网址看起来像目录。尝试在curl中执行请求(不使用镜像,只需一个简单的GET)并查看它是否发生在那里。

此外,打开HTTP访问并重写日志记录,看看在该级别发生了什么(注意,你必须在编译的配置中放置rewritelog指令,它不能在.htaccess中工作)。如果做不到这一点,请查看篡改数据,甚至更好的Wirehark等请求,以查看实际的请求。

需要考虑的其他事项:在你的apache conf中的MultiViews On可能会尝试添加后缀扩展,并且可能会被你的重写(不确定如何,但谁知道)而被奇怪地抓住 - 并且你的重写日志将显示。 mod_dir可能试图添加一个尾部斜杠(因为那些短网址看起来有点像目录),但是,你可能会看到它。

答案 7 :(得分:1)

只是一个猜测,但你安装了病毒扫描程序吗?有时他们会预取页面 - 从而导致两次点击。要检查access.log。

的外观

答案 8 :(得分:1)

我会在数据库端创建一个sproc / trigger来处理这个问题。

在特定事件(例如点击按钮)上从您的页面调用sproc。

您的问题可能来自意外的浏览器刷新,也可能来自数据库端的范围错误。

将代码重新设计为存储过程应该可以解决问题或帮助您找出问题所在。

答案 9 :(得分:0)

检查文件的编码。如果浏览器在页面中发现非ascii字母,则可能会使用其他编码重新加载页面。非ascii字母可以是æøå,Russion,中文或希伯来字母。即使您有一个指定编码的元标记,浏览器仍会重新加载页面并再次开始处理。

要解决此问题,请在高级浏览器(例如记事本++)中打开文件并指定编码。在Notepad ++中,这是格式&gt; UTF-8编码。如果您使用格式&gt;转换为UTF-8,文档的开头可能会出现一些奇怪的字节,因此使用Encode方法更安全。

答案 10 :(得分:0)

你使用Smarty吗?

- edit-- 我问这个是因为Smarty有一个错误,当你有一个没有在模板中定义src的img标签时,基础index.php将被包含两次。

如果您在同一页面中有一个img(您可能有ex)或iframe,则会发生同样的情况,因为基本脚本可能只在页面的一次刷新中显示两次(或更多)。

答案 11 :(得分:0)

随机:您的网页是否有自动刷新/重新加载功能,以获取最新评论,价格,更新等?这可能会导致第二次加载页面,这可能会影响您所看到的内容。

另外,你使用任何AJAX吗?

答案 12 :(得分:0)

您是否在页面(或包含的页面)的任何位置使用header("location: xxxxx")重定向?如果您在不立即调用exit()的情况下使用它们,脚本将继续执行。

例如,如果您对包含页面设置了一些$_SESSION变量的登录检查,那么使用header()重定向将您重定向到同一页面,则函数{{1之后没有调用,这意味着脚本的其余部分仍然会被执行,包括具有exit()功能的页面。但是,用户不会看到这一点,因为在客户端,它会在任何数据输出到浏览器之前重定向。

我们可以看到要验证的整个脚本吗?