PHP神秘的额外数据库插入

时间:2010-03-05 00:36:47

标签: php mysql debugging insert

我决定跟踪用户在我的网站上进行的搜索,因此我创建了一个名为“搜索”的MySQL表,其中包含一些简单的字段和一个模型(类),以便于插入和管理保存的搜索。

保存搜索的模型函数是:

public function create() {
    $q = $this->db->query("INSERT INTO 
                                `searches` (
                                    `section`,
                                    `keywords`,
                                    `results`,
                                    `location`,
                                    `date`
                                ) VALUES (
                                    %s, 
                                    %s,
                                    %s,
                                    %s,
                                    %s
                                )",
                                $this->section,
                                $this->keywords,
                                $this->results,
                                $this->location,
                                date('Y-m-d G:i:s'));
    $this->id = $this->db->last_insert($q);
}

...在我的控制器中,当页面加载时,我去了:

    /* lets save the search if there is one */
    if(isset($_GET['q'])) {
        $search = $this->load->model('Searches_Single',null);
        $search->set('section','sale');
        $search->set('keywords',$_GET['q']);
        $search->set('results',$grand_total);
        $search->set('location',$this->location->id);
        $search->create();
        unset($search);
    }

令我感到困惑的是,经常会插入1-4个重复行,而不是我期望的那一行。

没有循环,没有重定向......只是一个非常简单的页面加载。坦率地说,我相信这是我最后一次尝试这件事时发生的事。

更新

这不会发生在我的本地开发环境中......仅限于生产(可怕)。两者共享完全相同的代码......这可能是服务器的事情吗?

更新号码2 我发现这似乎发生在页面打开和关闭。 AKA - 我检查页面打开的时间,脚本记录搜索然后...然后我检查页面完成加载的时间,脚本似乎也在那里记录搜索...

GAHHH

5 个答案:

答案 0 :(得分:2)

您的代码示例并未真正深入了解可能导致此问题的原因。

您的搜索结果是否已分页?如果是这样,您确定仅在满足这些条件时才插入行吗?

  • 用户在第1页。
  • 用户第一次加载了第1页。

您可能要么在每个页面加载时插入,要么总是在第1页插入,如果用户访问第2页并决定返回第1页,则会导致重复。

答案 1 :(得分:1)

我遇到了类似的插入额外行的问题。当我从Perl的命令行运行INSERT查询时,它工作正常,但我没有编写的PHP脚本只会插入一行。我甚至尝试了一个不同的物理服务器,然后是虚拟机,所有人都尝试了最简单的代码:

<?php
mysql_connect("localhost", "USER", "PASSWORD") or die(mysql_error());
mysql_select_db("ci3") or die(mysql_error());
mysql_query("INSERT INTO trialsets (text) VALUES('values')");
header( 'Location: http://5.87.12.89/~tsbertalan/done.html' ) ;

echo "done";

最后,我尝试从我的笔记本电脑WGET-ing到我的php脚本的URL,它只在PHPMyAdmin中生成了一个新条目。然后,我有了尝试其他浏览器的天才想法。事实证明,出于某种原因,Chrome几次不得不多次点击该页面。提出

header( 'Location: http://5.87.12.89/~tsbertalan/done.html' ) ;
在mysql_query行解决问题之后

行。如果我按照良好做法并在处理POST输入后立即重定向到登陆页面,我甚至都不会注意到这一点,正如我最终打算做的那样。


答案 2 :(得分:0)

诊断此问题(IMHO)的最佳方法是在查询发生时将数据库查询简单地记录到/ tmp中的文件中。您应该能够在db类中执行此操作。如果你执行fopen / fwrite来记录,请确保使用追加“a”模式而不是“w”,否则重复的页面请求将覆盖日志,并且您将无法判断查询是否多次运行。我曾多次经历过一次页面加载2-3次,这是我没想到的,因为我忘记了一些重定向。 db查询日志应该可以帮助您查看是否存在格式错误的insert语句,或者是否正在运行重复的insert语句。

答案 3 :(得分:0)

在诊断出部分代码是否多次运行,并且您确定没有重定向后,您可以使用debug_backtrace来查看调用堆栈的功能。一个控制器我不能重定向,但它可能在不同的位置多次调用一段代码。在多次调用的部分中使用调试回溯,然后当你走出调用堆栈时,在调用之前添加一行记录以说“进入函数”,并在调用之后添加“离开函数”。

答案 4 :(得分:0)

我确定问题是,关注某个人到该页面以确定要显示哪个Google广告的Google漫游器会触发第二个页面加载,从而创建镜像数据库插入。有时在单页加载上多次。

叹息。 cmon谷歌。