使用带有绑定的PHP准备语句显示mySQL中的行
以下代码可以工作,但我担心SQL注入。 我试图将参数使用带有绑定的PHP准备语句显示mySQL中的行,php,mysql,mysqli,Php,Mysql,Mysqli,以下代码可以工作,但我担心SQL注入。 我试图将参数$S传递给一些PHP代码以显示测试结果。工作守则如下: <?php $S = $_GET['S']; // $sql = "SELECT `date`, `test` FROM `results` WHERE `id` = \"003-26\""; $servername = "localhost"; $username = "slowLearner"; $password = "myPasswor
$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();
?>
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简短回答。。。不要使用
查询
,使用执行
在准备
和绑定
if(!$stmt->bind_param('s', $S)){
die("Binding1 parameters failed: (" . $stmt->errno . ") " . $stmt->error);
}
使用execute
并检查返回(如果返回为FALSE,则表示发生错误。如果返回成功,SELECT将返回结果集)
如果我们没有使用mysqlnd(本机驱动程序),那么我们就不能使用get\u result
返回结果集
或者,我们可以做一个存储\u结果
,认识到大型结果集需要大量内存。如果我们不这样做,我们仍然可以获取行。(这是性能/内存的折衷。)
我们可以将行提取到绑定结果变量中
// http://php.net/manual/en/mysqli-stmt.bind-result.php
$stmt->bind_result($r_date, $r_test);
fetch
函数获取一行并填充绑定结果变量。注意,这些是对标量变量的引用fetch
不会像query
那样返回“resultset”对象
$cnt = 0;
while($stmt->fetch()) {
echo "Test Date: " . $r_date . ", Test score: " . $r_test . " (s)" . "<br>";
$cnt++;
}
if($cnt === 0) {
echo "zero results";
}
我们并不总是需要对语句进行close
,而是规范模式;这可以处理那些我们确实需要这样做的情况
// http://php.net/manual/en/mysqli-stmt.close.php
$stmt->close();
如果我们使用的是mysqlnd(原生驱动程序),那么我们可以使用
mysqli\u stmt\u get\u result
返回结果集,就像使用query
返回结果集一样
是否使用get_result
取决于代码的可移植性;如果您的代码需要mysqlnd
就我个人而言,我会使用PDO而不是mysqli。这里有一个示例演示如何查询。您的尝试确实容易发生SQL注入,您要查找的是
$stmt->execute()
。您看到了哪个错误?我显示一个stmt和一个查询running@Forbs-无此类错误,已更新问题以澄清。Thanks@ccKep-我尝试了$stmt->execute()
,但没有成功,根本没有足够的空间列出我尝试过的所有东西:-(我将查看链接,thanks@ccKep-我已经用修改过的代码更新了这个问题,但仍然没有成功。通过将MySQLi设置为抛出异常(就像PDO一样),可以节省大量的返回类型检查~mysqli_报告(mysqli_报告错误| mysqli_报告严格)
最好不要继续这种模式,因为不应该使用die来报告错误anyway@spencer7593-我非常感谢你坚持我的模式(显然)使用不正确。它帮助我修复了代码,现在一切都正常了。这是我第二次尝试使用mySQL和PHP做任何事情。对于这一点,我非常震惊地了解到SQL注入,并认为我在采取措施解决这一问题方面做得很好。我非常愿意使用PDO重写或了解其他改进方法。您的态度与许多StackOverflowers相同,这也是2017年大多数PHP代码仍然难看的原因之一。编写更好的代码不需要花费任何成本,但您坚持使用过时的有害代码approach@YourCommonSense谢谢你的奉承,但我真的不相信“我的态度”对你有多大影响“为什么大多数PHP代码仍然难看”。我认为“我的态度”对地球自转角速度的影响可能比对PHP代码的影响更大。请随意提供一个更好的答案。否决这个答案。编辑它。标记它以引起版主的注意。无论是什么让你感到温暖和亲切。你就是你。
$cnt = 0;
while($stmt->fetch()) {
echo "Test Date: " . $r_date . ", Test score: " . $r_test . " (s)" . "<br>";
$cnt++;
}
if($cnt === 0) {
echo "zero results";
}
$stmt->free_result();
// http://php.net/manual/en/mysqli-stmt.close.php
$stmt->close();