php mysqli_query 函数似乎运行了两次

Posted

技术标签:

【中文标题】php mysqli_query 函数似乎运行了两次【英文标题】:php mysqli_query function seems to run twice 【发布时间】:2015-04-01 10:09:12 【问题描述】:

这是我的网站的自定义功能,我需要在 iframe 中显示不同的 URL。我只想向用户显示每个 url 一次,所以我首先创建一个可用 url 数组,然后创建一个已经看到的 url 数组,最后比较两者以创建一个新数组以显示要显示的 url。然后我需要将此数组的第一个元素回显到 iframe 中。

问题似乎出在我执行进入数据库$entry = "INSERT INTO views VALUES ('', '$currentUsername', '$urlToShow')";的foreach函数中

我尝试了许多不同的方法,但无论我做什么,我都会从添加到数据库中的 $urlsToShow 数组中获得两个 url,并且只有一个在我的 iframe 中得到回显。结果是所有其他网站都被完全跳过,而用户永远看不到它们。

我已经打印了$urlsToShow 以确保它是一个数组,并且我做了同样的事情以确保$urlToShow 不是一个数组。

我什至不确定这是否是一个 php 问题...

代码如下:

function get_urls() 
    require 'config.php';
    global $con;
    global $currentUsername;
    $con = mysqli_connect($hostname, $dbusername, $dbpassword, $dbname);
    $query = "SELECT site_url FROM sites WHERE site_url IS NOT NULL";
    $result = mysqli_query($con, $query);
    // Get all the site urls into one array
        $siteUrls = array();
        $index = 0;
        while($row = mysqli_fetch_assoc($result)) 
            $siteUrls[$index] = $row['site_url'];
            $index++;
        
    $query2 = "SELECT site_url FROM views WHERE user = '$currentUsername' AND site_url IS NOT NULL";
    $result2 = mysqli_query($con, $query2);
    // Get urls the user has already seen into another array
        $seenUrls = array();
        $index = 0;
        while($row2 = mysqli_fetch_assoc($result2)) 
            $seenUrls[$index] = $row2['site_url'];
            $index++;
        
    // Compare the two arrays and create yet another array of urls to actually show
    $urlsToShow = array_diff($siteUrls, $seenUrls);
    if (!empty($urlsToShow)) 
        // Echo the url to show for the iframe within browse.php and add an entry to the database that the user has seen this site
        foreach ($urlsToShow as $urlToShow) 
            $entry = "INSERT INTO views VALUES ('', '$currentUsername', '$urlToShow')";
            mysqli_query($con,$entry);
            echo $urlToShow;
            break;
        
    
    // Show the allSeen file when all the ads are seen
    else echo 'includes/allSeen.php';
    mysqli_free_result($result);
    mysqli_close($con);

编辑

我接受了from here 的建议并缩小了函数,但同样的结果仍在发生。两个 url 被添加到视图表中,但只有两个中的第一个在 iframe 中得到回显。

function get_urls() 
    require 'config.php';
    global $con;
    global $currentUsername;
    $con = mysqli_connect($hostname, $dbusername, $dbpassword, $dbname);
    $query = "SELECT sites.site_url FROM sites LEFT JOIN views ON views.site_url=sites.site_url AND views.user='$currentUsername' WHERE sites.site_url IS NOT NULL AND views.site_url IS NULL";
    $result = mysqli_query($con,$query);
    $urlsToShow = mysqli_fetch_assoc($result);
    if (!empty($urlsToShow)) 
        $urlToShow = $urlsToShow['site_url'];
        echo $urlToShow;
        $entry = "INSERT INTO views VALUES ('', '$currentUsername', '$urlToShow')";
        mysqli_query($con,$entry);
    
    else echo 'includes/allSeen.php';
    mysqli_free_result($result);
    mysqli_close($con);

编辑 2

我也尝试过使用 php readfile();功能,因为我认为可能是 iframe 导致了这种情况。但不,同样的结果。也许我调用函数错误?

<iframe src="<?php get_urls();?>"/>

编辑 3

我还尝试在函数中将 iframe html 标记与 urlToShow 一起回显,以查看是否有所不同。不,它没有。

有人吗?

【问题讨论】:

【参考方案1】:

您可以访问 PHP 错误日志吗?我的调试路径有两个:

    在函数顶部添加static $calls = 0;,并在其正下方添加一行error_log('Called '.(++$called).' time(s).');。这将告诉您它是否作为同一请求的一部分被多次调用。

    如果您确定它在同一个请求中被多次调用,请尝试在 debug_backtrace 中记录第一个条目。

将以下内容放在函数的开头以记录调用函数的位置。

$trace = current(debug_backtrace());
error_log("Called by $trace['file']:$trace['line']");

结合起来,这两件事应该可以确定您的问题。

【讨论】:

我尝试添加 debug_print_backtrace();就在 mysqli_query 之前,我认为它只运行一次,因为结果是 #0 get_urls 调用... 关键是利用错误日志。我怀疑这是在发送输出后或在另一个请求时调用的。 我自己设法找出了问题所在。谢谢您的帮助。我真的很感激!【参考方案2】:

我花了两天时间才终于弄清楚了这个问题的真正原因。显然 Firefox 和 Chrome 也有一个错误(因为我测试了两者以防万一)。

tldr;

如果您将&lt;link&gt; 标签href 留空,则脚本将运行两次

示例(不要这样做):

&lt;link rel="Shortcut Icon" href="" type="image/x-icon"/&gt;

href 需要有一个值!

您可以在此处阅读更多信息:https://bugzilla.mozilla.org/show_bug.cgi?id=489115

【讨论】:

所以我们在这里遇到了一个我不知道如何解决的问题(MODS,请插话)。对于遇到的实际问题,我们有一个成功且可重复的解决方案,但最初的问题不包括实际的违规代码。只需将违规代码添加到 OP 就足够了(可能使以前的 cmets/answers 无效)? OP应该改写以适应吗?是否应该删除偏离主题的答案(一旦添加了违规代码)?这应该如何处理? (@ynef,别按我说的做,我们先得到一些反馈)。

以上是关于php mysqli_query 函数似乎运行了两次的主要内容,如果未能解决你的问题,请参考以下文章

mysqli_query函数的问题[重复]

PHP MySQL 事务捕获错误

mysqli_query():在PHPUnit中测试PHP函数时无法获取mysqli

php mysqli mysqli_query() mysqli_real_query()

PHP 数据库删除

PHP中的mysql_query()函数的返回值是啥?