php - 查询未插入数据库

标签 php mysql mysqli pdo prepared-statement

<分区>

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

有没有人看到我做错了什么,或者有什么好方法可以让我检查有什么问题吗?

//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.";
         }
        }
    }
}

最佳答案

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

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

我不确定您是从哪里养成的这种将变量作为字符串引用的习惯,但您需要改掉它。 '$x'$x 是两个截然不同的东西。在第一种情况下,它是 字面意思 '$x',在第二种情况下,它是 $x 变量恰好表示的任何内容。

像这样修复它:

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

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

只需直接绑定(bind)到源:

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

不要因为偏执狂或因为你正在做 cargo 崇拜编程而在某处的 YouTube 教程中看到它完成而随意运行 htmlspecialchars 之类的东西。该函数旨在用于仅显示 值,而不是存储它们。数据库中的数据应尽可能原始。

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

最大的问题是这受制于竞争条件,因为它不使用原子增量。编写计数器时,始终将更新作为单个语句的操作进行:

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

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

关于php - 查询未插入数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40138727/

相关文章:

php - 如何在多维非关联数组上使用 foreach 循环

php - 使用谷歌地图作为背景?

PHP-Mysql查询问题

mysql - 在 mySQL 数据库上创建搜索

mysql - 使用 PREPARE 和 EXECUTE 时遇到问题

php - 使用加入或别名获取具有相同报告电子邮件地址的用户的详细信息

php - 如果网站未打开,自动发送电子邮件

php - 在 PHP 函数 for 循环中将 mysql result() 转换为 mysqli

javascript - jQuery-Ajax : insert data from php

php - 是否可以使用 php 和 curl 在 mysql 中处理多个连接