以下代码有效,但我担心SQL注入。
我正在尝试将参数$S
传递给某些PHP代码以显示测试结果。工作代码如下:
<?php
$S = $_GET['S'];
// $sql = "SELECT `date`, `test` FROM `results` WHERE `id` = \"003-26\"";
$servername = "localhost";
$username = "slowLearner";
$password = "myPassword";
$dbname = "myDataBase";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check if id exists
if(!($stmt = $conn->prepare("SELECT `date`, `test` FROM `results` WHERE `id` = ?"))){
die("Prepare1 failed: (" . $conn->errno . ") " . $conn->error);
}
if(!$stmt->bind_param('s', $S)){
die("Binding1 parameters failed: (" . $stmt->errno . ") " . $stmt->error);
}
$sql = "SELECT `date`, `test` FROM `results` WHERE `id` = '".$S."'";
// But I believe the line above is prone to SQL injection so
// IDEALLY I would prefer to use something like:
// $result = $conn->query($stmt);
// but that simply does not work... (zero results is displayed)
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo "Test Date: " . $row["date"]. ", Test score: " . $row["test"]. " (s)" . "<br>";
}
} else {
echo "zero results";
}
$conn->close();
?>
我在代码中的评论显示我正在尝试(并且失败)使用带有绑定的预准备语句...我正在圈子里用这个,任何帮助都非常感激。< / p>
澄清:
没有这样的错误 - 当我尝试使用绑定时,我根本没有得到任何结果,并且else
if ($result->num_rows > 0) {
部分显示消息零结果
我确信拥有$sql
和$stmt
是不正确的,因为最终编写$sql
的方式使其容易注入...我想要的是什么show是我在绑定方面取得了多大的进展,并且此时我陷入了困境。
修改后的代码:
基于this example我修改了代码(见下文)。但是输出仍然显示zero results
,即使我知道有4行与查询匹配:$result = $conn->query($sql);
。修改后的代码如下:
if(!$stmt->bind_param('s', $S)){
die("Binding1 parameters failed: (" . $stmt->errno . ") " . $stmt->error);
}
$stmt->execute();
$stmt->bind_result($result);
$stmt->fetch();
if ($result->num_rows > 0) {
TIA -SL
答案 0 :(得分:2)
简短回答...请勿使用query
,请使用execute
prepare
和bind
if(!$stmt->bind_param('s', $S)){
die("Binding1 parameters failed: (" . $stmt->errno . ") " . $stmt->error);
}
使用execute
并检查返回(如果返回为FALSE则发生错误。如果成功,SELECT应该返回结果集)
// http://php.net/manual/en/mysqli-stmt.execute.php
if(!$stmt->execute()) {
die("execute failed: (" . $stmt->errno . ") " . $stmt->error);
}
如果我们不使用mysqlnd(本机驱动程序),那么我们就不能使用get_result
来返回结果集。
可选地,我们可以执行store_result
,认识到大型结果集将需要大量内存。如果我们不这样做,我们仍然可以获取行。 (它的性能/内存权衡。)
// http://php.net/manual/en/mysqli-stmt.store-result.php
$stmt->store_result();
我们可以将行提取到绑定结果变量
// http://php.net/manual/en/mysqli-stmt.bind-result.php
$stmt->bind_result($r_date, $r_test);
fetch
函数获取一行并填充我们的绑定结果变量。请注意,这些是对标量变量的引用; fetch
不会返回query
之类的“结果集”对象。
$cnt = 0;
while($stmt->fetch()) {
echo "Test Date: " . $r_date . ", Test score: " . $r_test . " (s)" . "<br>";
$cnt++;
}
if($cnt === 0) {
echo "zero results";
}
如果我们做了store_result
,我们应该释放内存
$stmt->free_result();
我们并不总是需要做一个close
的陈述,而是它的规范模式;这就处理了我们确实需要这样做的情况。
// http://php.net/manual/en/mysqli-stmt.close.php
$stmt->close();
如果我们使用mysqlnd(本机驱动程序),那么我们可以使用mysqli_stmt_get_result
返回结果集,就像我们使用query
一样。
是否使用get_result
取决于您的代码需要多么便携;如果你的代码需要mysqlnd。
就个人而言,我使用PDO而不是mysqli。