【问题标题】:PHP SQL query doesnt return a resultPHP SQL查询不返回结果
【发布时间】:2018-09-30 19:04:45
【问题描述】:

我在 web 应用中有一个按钮,允许用户请求特殊格式的数字。当用户单击此按钮时,会运行 2 个脚本。第一个功能齐全,查看数字表找到最大数字并将其递增 1。(这不是主键)部分工作的第二个脚本获取当前日期并运行 SQL 查询以获取哪个时期该日期落入。(在这种情况下,期间并不总是等于一整月)我知道这个脚本至少部分工作,因为我可以访问该脚本文件中调用的 $datetoday 变量。但是,它不会从周期表中返回请求的数据。任何人都可以帮助我确定我做错了什么?

<?php
    include 'dbh.inc.php';
    $datetoday = date("Ymd");
    $sql = "SELECT p_num FROM periods where '$datetoday' BETWEEN p_start AND p_end";
    $stmt = mysqli_stmt_init($conn);
    if(!mysqli_stmt_prepare($stmt, $sql)) {
        header("Location: ../quote.php?quotes=failed_to_write");
        exit();
    } else {
        mysqli_stmt_execute($stmt);
        mysqli_stmt_store_result($stmt);
        $result = mysqli_stmt_get_result($stmt);
        $row = mysqli_fetch_assoc($result);
        $pnum = $row;
        mysqli_stmt_close($stmt);
    }

如果对任何人有帮助,我将我的代码发布到https://github.com/cwilson-vts/Quote-Appliction

【问题讨论】:

  • BETWEEN p_start AND p_end 这里的 p_start/p_end 是什么?
  • p_start 是周期表中列出周期开始的列名。 p_end 是周期表中的列名,即周期的结束日期。 p_num 是我分配给该范围内日期的期间编号。
  • 此条件不正确BETWEENfield 的值应介于 start 和 and 之间时使用。
  • 当我从 phpmyadmin 查询数据库时它可以工作。那么解决方法就是: SELECT p_num from PERIODS where $datetoday > p_end AND $datetoday
  • 如果您将 $sql 更改为 Select 1 from period,您的脚本可以正常工作吗?

标签: php mysql xampp


【解决方案1】:

所以首先,我不使用 msqli,也从未学过它。但是,我相信我了解您想要做的事情的要点。我使用 PDO 是因为我觉得它更易于使用、更易于阅读,而且这也是我一开始就学到的。这有点像苹果与三星……没有一种产品是完全错误或正确的。并且各有优缺点。我将为您提供的内容将采用 PDO 形式,因此我希望您能够使用它。如果你不能,那么不用担心。

我想首先解决我看到的一件主要事情,那就是您将变量直接交错到 mysql 语句中。这不被认为是标准做法,并且由于 sql 注入而不安全。作为参考,我希望您阅读以下网站:

http://php.net/manual/en/security.database.sql-injection.php

http://php.net/manual/en/pdo.prepared-statements.php

接下来,我注意到您使用 datetime 作为变量名。我建议不要这样做,因为这在大多数编程语言中都是保留的,并且可能很棘手。因此,相反,我将对其进行一些不敏感的更改,例如$now = "hello world data";

我也没有看到你会在哪里打印结果?或者你只是没有包括那个? 要考虑的另一件事:您的日期时间变量与您存储在数据库中的格式是否相同?因为如果没有,你每次都会返回 0 个结果。还要确保它也是正确的时区。因为那真的会惹恼你。我也会在下面的代码中向您展示这一点。

现在开始实际代码!我将为您提供从 db 连接代码到 sql 执行的所有内容。

数据库连接文件:

<?php

    $host = '127.0.0.1';
    $user = 'root';
    $pw = '';
    $db = 'test'; // your db name here (replace 'test' with whatever your db name is)

    try {
        // this is the variable will call on later in the main file
        $conn = new PDO("mysql:host=$host;dbname=$db;", $user, $pw);
    } catch (PDOException $e) {
        // kills the page and returns mysql error
        die("Connection failed: " . $e->getMessage());
    }
?>

数据文件:

<?php
    // calls on the db connection file
    require 'dbconfig.php';

    // set default date (can be whatever you need compared to your web server's timezone). For this example we will assume the web server is operating on EST.
    date_default_timezone('US/Eastern');
    $now = date("Ymd");

    // check that the $now var is set
    if(isset($now)) {
        $query = $conn->prepare("SELECT p_num FROM periods WHERE p_start BETWEEN p_start AND :now AND p_end BETWEEN p_end AND :now");
        $query->bindValue(':now', $now);
        if($query->execute()) {
            $data = $query->fetchAll(PDO::FETCH_ASSOC);
            print_r($data); // checking that data is successfully being retrieved (only a troubleshooting method...you would remove this once you confirm it works)
        } else {
            // redirect as needed and print a user message
            die("Something went wrong!");
        }
        $query->closeCursor();
    }
?>

我要提及的另一件事是,确保您遵循正当程序进行故障排除。如果它不起作用并且我没有收到任何错误,我通常首先从查询级别开始。我检查以确保我的查询正确执行。为此,我进入我的数据库并手动执行它。如果这有效,那么我想检查我是否真的收到了我声明的变量的值。如您所见,我检查以确保设置了 $now 变量。如果不是,则该代码块甚至不会运行。 PHP 在这方面可能相当棘手和挑剔,所以一定要检查一下。如果您也不确定变量的设置是什么,只需执行echo $now 即可回显或打印它

如果您还有其他问题,请告诉我。希望对你有帮助!

【讨论】:

  • 谢谢@rhuntington!我会试一试,然后告诉你。
  • 这做了一些事情,但它没有做它需要做的事情。它返回“数组”而不是数组中 p_num 的值。当我在 SQL 中运行您的查询时,将 :now 替换为 20181001 我会列出 p_num 01-09,但今天的实际 p_num 不是 \which 是 10。
  • 好的,请您将打印出来的内容复制到这里,然后请告诉 p_start 和 p_end 中的数据类型。是时间戳吗?还是一个varchar?我不知道数据库中的数据类型是什么。
  • 这是输出: Array ( [0] => Array ( [p_num] => 01 ) [1] => Array ( [p_num] => 02 ) [2] => Array ( [p_num] => 03 ) [3] => 数组 ( [p_num] => 04 ) [4] => 数组 ( [p_num] => 05 ) [5] => 数组 ( [p_num] => 06 ) [ 6] => 数组 ( [p_num] => 07 ) [7] => 数组 ( [p_num] => 08 ) [8] => 数组 ( [p_num] => 09 ) )
  • 我使用的是日期数据类型
【解决方案2】:

我想我知道我做错了什么,比我更懂 PHP 的人肯定会说。在我上面的代码中,我使用了mysqli_stmt_store_result 我相信那是在我打算之前清除我的变量。我改变了这一点,并重新编写了我的查询,使其更简单。

    <?php
include 'dbh.inc.php';
$datetoday = date("Ymd");
$sql = "SELECT p_num FROM periods WHERE p_start <= $datetoday order by p_num desc limit 1";
$stmt = mysqli_stmt_init($conn);
if(!mysqli_stmt_prepare($stmt, $sql)) {
    header("Location: ../quote.php?quotes=failed_to_write");
    exit();
} else {
    mysqli_stmt_execute($stmt);
    $result = mysqli_stmt_get_result($stmt);
    while( $row = mysqli_fetch_assoc($result)) {
    $pnum = $row['p_num'];
    echo $pnum;
    }
    mysqli_stmt_close($stmt);
}

感谢@rhuntington 和@nick 提供帮助。对不起,我真是个白痴。

【讨论】:

  • 不是白痴。很高兴你找到了你要找的东西。迫在眉睫的查询,这是有道理的。我不明白你在尝试什么。至于阵列的打印,请记住这只是一种测试方法,以显示您得到的结果。您当然会为您的站点以漂亮整洁的方式打印阵列。恭喜你弄明白了!请记住,每个人都从某个地方开始。
猜你喜欢
  • 2012-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-13
  • 1970-01-01
相关资源
最近更新 更多