查询未插入数据库

时间:2016-10-19 18:13:22

标签: php mysql mysqli pdo prepared-statement

我正在尝试实施点击计数系统。我在此链接Click here to see code中使用以下代码,但将其更改为现代标准。最初我收到了msqli_real_escape_字符串的错误,但我相信我解决了它(没有错误)。现在,我没有收到任何错误,但查询没有发送到我的数据库。我正在使用ini_set('display_errors', 1); error_reporting(E_ALL);进行错误检查。我还调用了我的$consession in和ini文件,因此会话和连接不是问题。

有没有人看到我做错了什么,或者有什么好方法我可以检查看看哪些不起作用?

//create current page constant
$curPage = mysqli_real_escape_string($con,htmlspecialchars($_SERVER['PHP_SELF']));

//set number of clicks variable to 0
$clicks = 0;

//do not recount if page currently loaded
if($_SESSION['page'] != $curPage) {
   //set current page as session variable
   $_SESSION['page'] = $curPage;

    $click_sql = "
    SELECT *
    FROM click_count
    WHERE page_url = ?
    ";
    if (!$click_stmt = $con->prepare($click_sql)) {
        $click_stmt->bind_param("s", $curPage);
        $click_stmt->execute();
        $num_rows = $click_stmt->fetchColumn();
        if (!$click_stmt->errno) {
            // Handle error here
        }
        $stmt->bind_result($click_id, $page_url, $page_count);
    } elseif ($num_rows == 0) {
        //try to create new record and set count for new page to 1
         //output error message if problem encountered
            $click_insert_stmt = "
            INSERT INTO click_count 
            (page_url, page_count)
            VALUES(?, ?)";

         if(!$click_stmt = $con->prepare($click_insert_stmt)) {
            $click_insert_stmt->execute(array('$curPage',1));
            echo "Could not create new click counter.";
         }
         else {
            $clicks= 1;
         }
    } else {
    //get number of clicks for page and add 1     fetch(PDO::FETCH_BOTH)
        while($click_row = $click_insert_stmt->fetch(PDO::FETCH_BOTH)) {
            $clicks = $row['page_count'] + 1;
            //update click count in database;
            //report error if not updated

            $click_update_stmt = "
            UPDATE click_count
            SET page_count = ?
            WHERE page_url = ?
            ";
            if(!$click_stmt = $con->prepare("$click_update_stmt")) {
                $click_update_stmt->execute(array('$clicks', '$curPage')); 
                echo "Could not save new click count for this page.";
         }
        }
    }
}

编辑:新更新的代码

// ********Page count************

//create current page constant
$curPage = mysqli_real_escape_string($con,($_SERVER['PHP_SELF']));

//set number of clicks variable to 0
$clicks = 0;

//do not recount if page currently loaded
if($_SESSION['page'] != $curPage) {
   //set current page as session variable
   $_SESSION['page'] = $curPage;

    $click_sql = "
    SELECT *
    FROM click_count
    WHERE page_url = ?
    ";
    if (!$click_stmt = $con->prepare($click_sql)) {
        $click_stmt->bind_param("s", $_SERVER['PHP_SELF']);
        $click_stmt->execute();
        $num_rows = $click_stmt->fetchColumn();
        if (!$click_stmt->errno) {
            // Handle error here
        }
        $stmt->bind_result($click_id, $page_url, $page_count);
    } elseif ($num_rows == 0) {
        //try to create new record and set count for new page to 1
         //output error message if problem encountered
            $click_insert_stmt = "
            INSERT INTO click_count 
            (page_url, page_count)
            VALUES(?, ?)";

         if(!$click_stmt = $con->prepare($click_insert_stmt)) {
            $click_insert_stmt->execute(array($curPage,1));
            echo "Could not create new click counter.";
         }
         else {
            $clicks= 1;
         }
    } else {
    //get number of clicks for page and add 1     fetch(PDO::FETCH_BOTH)
        while($click_row = $click_insert_stmt->fetch(PDO::FETCH_BOTH)) {
            $clicks = $row['page_count'] + 1;
            //update click count in database;
            //report error if not updated

            $click_update_stmt = "
            UPDATE click_count
            SET page_count=page_count+1
            WHERE page_url = ?
            ";
            if(!$click_stmt = $con->prepare("$click_update_stmt")) {
                $click_update_stmt->execute(array($curPage)); 
                echo "Could not save new click count for this page.";
         }
        }
    }
}

1 个答案:

答案 0 :(得分:3)

看起来你正在做很多像这样的事情:

$click_update_stmt->execute(array('$clicks', '$curPage'));

我不确定你在哪里习惯将变量引用为字符串,但你需要放弃它。 '$x'$x是两个截然不同的东西。在第一种情况下,它字面上 '$x',在第二种情况下,无论$x变量恰好代表什么,都是

修复如下:

$click_update_stmt->execute(array($clicks, $curPage));

此外,由于您正在使用准备好的语句,顺便说一句,您不需要也不应该手动转义您的值。将它们应用于bind_param的占位符是安全的方法。执行任何其他转义会破坏数据。

直接绑定到源:

$click_stmt->bind_param("s", $_SERVER['PHP_SELF']);

不要随意妄想输入htmlspecialchars这样的内容,或者因为你正在进行货物编程,你在某个地方的YouTube教程中看到了它。该函数仅用于显示值,而不是存储它们。数据库中的数据应尽可能原始。

这段代码存在很多问题,其中一个令我感到困惑的是为什么会出现很多代码。记住SELECT *,然后将结果绑定到任意变量是麻烦,您的架构可能会更改,然后您的代码不同步。如果这样做,只要有可能将行作为关联数组获取,那么您只需重新命名已删除的列。

最大的问题是它受竞争条件的影响,因为它没有使用原子增量。在编写计数器时,总是将您的更新作为单个语句的操作进行:

UPDATE click_count SET page_count=page_count+1 WHERE page_url=?

您读取计数,递增计数,然后将其写回数据库的方法意味着如果另一个操作同时运行,您就会引发问题,这很可能是点击计数器代码。