简体   繁体   English

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

[英]properly parameterize mysqli query and print multiple rows

I know this question if floating just about everywhere but I can't seem to apply it to my own problem. 我知道这个问题如果漂浮在各处,但我似乎无法将其应用于我自己的问题。 I have been using non parameterized queries which makes my project extremely vulnerable to SQL injection 我一直在使用非参数化查询,这使我的项目极易受到SQL注入的攻击

Plot: 情节:

I have a form where you enter a date. 我有一个表格,您可以在其中输入日期。 PHP will get the date and use it in a query to retrieve multiple rows of information. PHP将获取日期并在查询中使用它来检索多行信息。

How do I parametize my mysqli queries and print out the multiple rows? 如何参数化我的mysqli查询并打印出多行? This is what I have so far: 这是我到目前为止:

HTML 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 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 loop PHP循环

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

I have based my code from the PHP manual and ended up getting overwhelmed. 我根据PHP手册编写了我的代码,最终变得不堪重负。 I'm not even sure if I'm on the right track in preparing my queries let alone attempting how to display the data. 我甚至不确定我是否正在准备我的查询,更不用说尝试如何显示数据了。 Any help would be appreciated! 任何帮助,将不胜感激!

note - if someone could explain $stmt->bind_param("si", todayDateFrom , todayDateTo ); 注意 - 如果有人可以解释$stmt->bind_param("si", todayDateFrom , todayDateTo ); specifically the "si" that would be fantastic. 特别是那个太棒了的“si”。 I just don't understand what its purpose is. 我只是不明白它的目的是什么。

--SOLUTION-- - 解 -

Thanks to all the answers I was able to get my first parameterized query to work. 感谢所有的答案,我能够让我的第一个参数化查询工作。

As suggested, I removed the " ' " that was surrounding " ? " in my query. 正如所建议的那样,我在查询中删除了围绕“?”的“'”。

I then changed the bind_param "si" to "ss" because i was binding 2 strings, not a string and an integer. 然后我将bind_param “si”更改为“ss”,因为我绑定了2个字符串,而不是字符串和整数。

I then binded the results (in this example I have 3 columns in the table) 然后我将结果绑定(在本例中我在表中有3列)

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

Because I don't currently have a 3rd party driver installed, I had to display the results like so: 因为我目前没有安装第三方驱动程序,所以我必须显示结果:

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

Your existing code works just fine, except you have one tiny mistake, from the manual PHP MySQLi bind_param manual 你现有的代码工作得很好,除了你有一个小错误,来自手册PHP MySQLi bind_param手册

i corresponding variable has type integer 对应的变量有整数类型

d corresponding variable has type double d对应的变量有double类型

s corresponding variable has type string s对应的变量有类型字符串

So from above we can see that, "i" is used if you want to tell the MySQLi that your parameter is in fact integer, and "s" is used if you want to tell MySQLi that your paramater is in fact an string. 因此,从上面我们可以看到,如果你想告诉MySQLi你的参数实际上是整数,则使用“i”,如果你想告诉MySQLi你的参数实际上是一个字符串,则使用“s”。

So please replace 所以请更换

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

with

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

and remove 并删除

'

from the parameter place holders (ie '?' should be replaced with ?) 从参数占位符(即'?'应替换为?)

And your code of sending the parameterized statement will work just fine 您发送参数化语句的代码将正常工作

Fetching the results 获取结果

From the manual PHP MySQLi fetch what fetch does is: 从手册PHP MySQLi获取 fetch的作用:

Fetch results from a prepared statement into the bound variables 将预准备语句的结果提取到绑定变量中

What you are looking for is get_result . 你在寻找的是get_result From the manual it: 从手册中:

Gets a result set from a prepared statement 从预准备语句中获取结果集

So you can fetch the data using the following code: 因此,您可以使用以下代码获取数据:

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

Here is the documentation for fetch_array 这是fetch_array的文档

You need to change following line: 您需要更改以下行:

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

To: 至:

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

Reason: If you look at the following image you can see that i is for Integer and s is for String . 原因:如果您查看下图,您可以看到iIntegersString

在此输入图像描述

The date parameter should be provided as String , hence use s . date参数应该以String形式提供,因此使用s

Reference: PHP mysqli_stmt::bind_param documentations. 参考:PHP mysqli_stmt :: bind_param文档。

Also you need to update your SQL statement: 您还需要更新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");

To: 至:

$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");

Reason: Parameter mark should not be surrounded by ' . 原因:参数标记不应被'包围。

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

During param bind you are mentioning that first varible is string and 2nd is integer but as per your code it should be 在param绑定期间,你提到第一个变量是字符串而第二个是整数但是根据你的代码它应该是

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

Please remove single quotes from your query as well and should be something like this 请从查询中删除单引号,并且应该是这样的

$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");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM