正确参数化mysqli查询并打印多行

时间:2014-09-18 05:47:28

标签: php mysql sql mysqli while-loop

我知道这个问题如果漂浮在各处,但我似乎无法将其应用于我自己的问题。 我一直在使用非参数化查询,这使我的项目极易受到SQL注入

简介:

我有一个表格,您可以在其中输入日期。 PHP将获取日期并在查询中使用它来检索多行信息。

如何参数化我的mysqli查询并打印出多行?这就是我到目前为止所做的:

HTML

<form action="#" class="form-horizontal" method="post">
    <label for="fromDate" class="control-label">Date from:</label>
    <input type="date" id="fromDate" class="datepicker" name="searchDate" value="<?php echo $searchDate; ?>">
    <button type="submit" class="btn">Go</button>
    <input type="hidden" name="formIdentifier" value="mainSearch" />
</form>

PHP

if($_POST['formIdentifier'] == "mainSearch"){
    //get date from form
    $searchDate = $_POST['searchDate'];
    $todayDateFrom = $searchDate." 00:00:00";
    $todayDateTo = $searchDate." 23:59:59";
    $stmt = $conn->prepare("SELECT G.* FROM Groups AS G, Customers AS C 
            WHERE C.travel_Date >= '?'
            AND   C.travel_Date <= '?'
            AND C.customer_ID = G.leader_ID");
    $stmt->bind_param("si", todayDateFrom , todayDateTo );
    $stmt->execute();
    /* bind variables to prepared statement */
    $stmt->bind_result($col1, $col2);
}

PHP循环

while ($stmt->fetch()) {
    //Display copious amounts of data.
}

我已根据PHP手册编写代码,最终导致不堪重负。我甚至不确定我是否正在准备我的查询,更不用说尝试如何显示数据了。任何帮助将不胜感激!

注意 - 如果有人能够特别解释$stmt->bind_param("si", todayDateFrom , todayDateTo );那将是非常棒的“si”。我只是不明白它的目的是什么。

- 解 -

感谢所有答案,我能够使我的第一个参数化查询起作用。

根据建议,我在查询中删除了围绕“?”的“'”。

然后我将bind_param“si”更改为“ss”,因为我绑定了2个字符串,而不是字符串和整数。

然后我将结果绑定(在本例中我在表格中有3列)

$stmt->bind_result($group_ID, $leader_ID, $gDate);

因为我目前没有安装第三方驱动程序,所以我必须显示结果:

while ($stmt->fetch()) {
    echo "group_ID: ".$group_ID."<br />";
    echo "leader_ID: ".$leader_ID."<br />";
    echo "group_Date: ".$group_Date."<br />";
}

3 个答案:

答案 0 :(得分:2)

您的现有代码工作得很好,除了您有一个小错误,来自手册PHP MySQLi bind_param manual

i 相应的变量具有整数

d 相应变量的类型为double

s 相应的变量具有类型字符串

从上面我们可以看到,如果您想告诉MySQLi您的参数实际上是整数,则使用“i”,如果您想告诉MySQLi您的参数实际上是一个,则使用“s”字符串。

所以请更换

$stmt->bind_param("si", todayDateFrom , todayDateTo );

$stmt->bind_param("ss", todayDateFrom , todayDateTo );

并删除

  

来自参数占位符的

(即“?”应替换为?)

您发送参数化语句的代码将正常工作

获取结果

从手册PHP MySQLi fetch获取的内容是:

  

从准备好的语句中获取结果到绑定变量

您要找的是get_result。从手册中可以看出:

  

从预准备语句

获取结果集

因此,您可以使用以下代码获取数据:

$result = $stmt->get_result();
    while ($row = $result->fetch_array(MYSQLI_NUM))
    {
        foreach ($row as $r)
        {
            print "$r ";
        }
        print "\n";
    }

以下是fetch_array

的文档

答案 1 :(得分:1)

您需要更改以下行:

$stmt->bind_param("si", todayDateFrom , todayDateTo );

致:

$stmt->bind_param("ss", todayDateFrom , todayDateTo );

原因:如果您查看以下图片,则可以看到i适用于Integers适用于String。< / p>

enter image description here

日期参数应以String的形式提供,因此请使用s

参考:PHP mysqli_stmt::bind_param文件。

您还需要更新SQL语句:

$stmt = $conn->prepare("SELECT G.* FROM Groups AS G, Customers AS C 
        WHERE C.travel_Date >= '?'
        AND   C.travel_Date <= '?'
        AND C.customer_ID = G.leader_ID");

要:

$stmt = $conn->prepare("SELECT G.* FROM Groups AS G, Customers AS C 
        WHERE C.travel_Date >= ?
        AND   C.travel_Date <= ?
        AND C.customer_ID = G.leader_ID");

原因:参数标记不应被'包围。

答案 2 :(得分:0)

$stmt->bind_param("si", todayDateFrom , todayDateTo );

在param绑定期间,你提到第一个变量是字符串而第二个是整数但是根据你的代码它应该是

$stmt->bind_param("ss", $todayDateFrom , $todayDateTo );

请从查询中删除单引号,应该是这样的

$stmt = $conn->prepare("SELECT G.* FROM Groups AS G, Customers AS C 
            WHERE C.travel_Date >= ?
            AND C.travel_Date <= ?
            AND C.customer_ID = G.leader_ID");