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()
的变量数必须与您在查询中选择的列数完全匹配,这一点很重要。这些变量将保存每次迭代的列值。
这是一个起点,可引导您朝着正确的方向前进。相应地更改 column1
到 column3
的名称(在查询字符串 (prepare()
) 和结果绑定 bind_result()
中)。如前所述,这些是一对一的匹配。您还必须相应地更改表的名称,myTableName
目前只是一个占位符(column1
到 column3
也是如此)。
// 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 准备好的语句和 mysqli_real_escape_string