【问题标题】:SQL Query: Incrementing by two instead of 1SQL 查询:增加 2 而不是 1
【发布时间】:2009-07-24 21:40:56
【问题描述】:

我正在尝试通过将表中的整数值增加 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"
  }
}

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

同样从日志文件来看,脚本好像被调用了 3 次??

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]

【问题讨论】:

  • 如果您使用其他浏览器(没有相同插件的浏览器)请求页面,是否也会发生这种情况?
  • 是的,同样的事情发生在不同的浏览器上。在同一个浏览器上同一个浏览器!
  • 你能发布你的完整剧本吗?不仅仅是eh函数片段

标签: php sql debugging mysql


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    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 实例中)。否则你的脚本被调用了两次。

    【讨论】:

    • 强大的调试功能。我已经用我得到的输出更新了我的问题。
    【解决方案3】:

    没有涉及触发器,是吗?

    【讨论】:

    • 很抱歉成为一个菜鸟 - 但你是什么意思“没有触发器”?我确实自己调用了该函数,但仅此而已。
    • 触发器是当表有更新/插入/删除事件时运行的一段代码。我很确定 MySQL 有它们。通常,当我发现无法解释的行为时,我可以将其追踪到触发器。
    【解决方案4】:

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

    您能否将请求也记录到您的 php 应用程序中,看看您是否被浏览器击中两次?

    【讨论】:

      【解决方案5】:

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

      【讨论】:

      • 哦。我需要练习我的打字技巧,这样我才能先写出我的答案。
      【解决方案6】:

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

      此外,打开 HTTP 访问并重写日志记录并查看该级别发生的情况(注意,您必须将 rewritelog 指令放在编译的配置中,它不会在 .htaccess 中工作)。如果做不到这一点,请在 tamperdata 甚至更好的 wireshark 中查看请求,以查看正在发出的实际请求。

      其他需要考虑的事情:您的 apache conf 中的 MultiViews On 可能会尝试添加后缀扩展名,并且它可能会被您的重写奇怪地捕获(不确定如何,但谁知道) - 您的重写日志将显示. mod_dir 可能会尝试添加尾部斜杠(因为这些短 url 看起来有点像目录),但是,您可能会看到。

      【讨论】:

        【解决方案7】:

        这个页面是错误处理页面吗?

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

        鉴于文件确实似乎不止一次运行,可能会发生一些重定向循环 - 您的 .htaccess 文件中有什么?

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

        【讨论】:

        • 好问题。我已经更新了我的 htaccess 以显示其中的内容
        【解决方案8】:

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

        【讨论】:

          【解决方案9】:

          我会创建一个存储过程/触发器来在数据库端处理这个问题。

          在特定事件(如按钮点击)上从您的页面调用存储过程。

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

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

          【讨论】:

            【解决方案10】:

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

            要解决此问题,请在高级浏览器(例如 notepad++)中打开您的文件并指定编码。在 Notepad++ 中,这是在 UTF-8 格式 > 编码中。如果使用Format>Convert to UTF-8,文档开头可能会出现一些奇怪的字节,所以使用Encode方法比较安全。

            【讨论】:

            • 你的意思是浏览器要再次从服务器获取数据?我想它应该从它从服务器获得的 http 流中重新渲染页面。你能在不涉及客户端/浏览器的情况下运行这段代码,看看它是否仍然失败?
            • 我亲身经历过这个问题,虽然它是使用会话计数器。不过同样的概念。检验这一理论的最简单方法就是删除所有非 ascii 字符,包括可能来自数据库的任何字符。
            【解决方案11】:

            你使用 Smarty 吗?

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

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

            【讨论】:

              【解决方案12】:

              随机:您的页面是否有任何自动刷新/重新加载功能,以获取最新的 cmets、价格、更新等?这可能会导致页面的第二次加载,这可能会执行您所看到的操作。

              另外,你使用任何 AJAX 吗?

              【讨论】:

                【解决方案13】:

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

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

                我们可以查看整个脚本来验证吗?

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-08-12
                  • 2011-04-05
                  • 2020-05-15
                  • 1970-01-01
                  • 2013-03-04
                  • 2017-12-04
                  相关资源
                  最近更新 更多