mysqli 使用 select * 和准备好的语句和查询

Posted

技术标签:

【中文标题】mysqli 使用 select * 和准备好的语句和查询【英文标题】:mysqli using select * with a prepared statement and query 【发布时间】:2018-12-11 02:59:05 【问题描述】:

我已经筋疲力尽地寻找并寻找我的确切情况。我想了解为什么这不起作用,我还想确保这个逻辑对于注入黑客来说是更安全。我知道没有什么是 100% 安全的。以下代码不起作用:

$query= mysqli_prepare($con,"SELECT * FROM *table*
    WHERE Resource = ? AND WorkDate >= ? AND WorkDate <= ? ORDER BY WorkDate, StartTime" );


mysqli_stmt_bind_param($query, "sss", $resource, $from, $to);
mysqli_execute($query);

if (!mysqli_stmt_execute($query))

    die('Error: ' . mysqli_error());

mysqli_stmt_store_result($query);

mysqli_stmt_fetch($query);

$result= mysqli_query($con,$query, MYSQLI_STORE_RESULT); // or die("Could not get results: ".mysqli_error()); 
while($rows=mysqli_fetch_array($result))<fill in table>

此代码在 $result 行中终止。我已经完成了查询和所有变量的 var_dumps。当我 var_dump 查询时,它会正确告诉我受影响的行。所以对我来说,这意味着准备好的声明正在发挥作用。但是当我尝试运行查询时,我可以获取它以在我的屏幕上输出数据。

现在这适用于 mysql,但我正在尝试将其转换为 mysqli 以避免注入。本来整个 sql 语句就位,但现在使用准备好的语句来避免这种情况。

【问题讨论】:

错误信息是什么?您已设置错误报告级别 (E_ALL) 并检查日志或显示错误? FROM *table* 那是你的实际代码吗? 另外$query是一个mysqli语句对象,你不能把它传递给mysqli_query() 针对mysqli使用的有用的通用错误追踪ini_set('display_errors', 1); ini_set('log_errors',1); error_reporting(E_ALL); mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);添加到脚本的顶部。这将强制任何mysqli_ 错误生成一个您可以在浏览器上看到的异常,并且其他错误也将在您的浏览器上可见。 table 只是一个占位符。应该是斜体。 【参考方案1】:

您需要了解准备好的语句和常规查询之间的区别。一旦你从一个准备好的语句开始,你必须以这种方式运行直到结束(除非你通过mysqli_stmt::get_result()存储结果,那么你可以使用mysqli::fetch_assoc()和类似的功能——这个答案没有涵盖,请参阅手册示例)。

鉴于您的代码中有*table*,我认为这是不正确的。请相应地更改下面查询的前两行(您选择的列和您选择它们​​的表格)。

提供给bind_result() 的变量数必须与您在查询中选择的列数完全匹配,这一点很重要。这些变量将保存每次迭代的列值。

这是一个起点,可引导您朝着正确的方向前进。相应地更改 column1column3 的名称(在查询字符串 (prepare()) 和结果绑定 bind_result() 中)。如前所述,这些是一对一的匹配。您还必须相应地更改表的名称,myTableName 目前只是一个占位符(column1column3 也是如此)。

// Prepare the query
$stmt = $con->prepare("SELECT column1, column2, column3 
                       FROM myTableName
                       WHERE Resource = ? 
                         AND WorkDate >= ? 
                         AND WorkDate <= ? 
                       ORDER BY WorkDate, StartTime");
if (!$stmt) 
    // Check for errors, if the prepare failed, it will return 'false'
    echo "An unexpected error occurred, check the logs.";
    error_log($con->error);
    exit;


// Bind the parameters (?)  in the query and execute it
$stmt->bind_param("sss", $resource, $from, $to);
if (!$stmt->execute()) 
    echo "An unexpected error occurred, check the logs.";
    error_log($stmt->error);
    $stmt->close();
    exit;


// Bind the results of each column into a variable
$stmt->bind_result($column1, $column2, $column3);

// In this loop we use the variables that we bound in the function bind_result above
// In this example, we simply print their values
while ($stmt->fetch()) 
    echo "$column1 -- $column2 -- $column3";


// Close the statement after use!
$stmt->close();

手册也是阅读示例的好地方

mysqli::prepare() mysqli::bind_param() mysqli::bind_result()

【讨论】:

以上是关于mysqli 使用 select * 和准备好的语句和查询的主要内容,如果未能解决你的问题,请参考以下文章

从 mysql_query 转换为准备好的语句 (mysqli/PDO)?必要的?

同一页面上的准备语句和 mysqli_query

mysqli 准备好的语句和 mysqli_real_escape_string

bind_result 成数组 PHP mysqli 准备好的语句

使用 mysqli 和准备好的语句时命令不同步 [重复]

如何在mysqli准备好的语句中使用SQL LIKE子句[重复]