猿问

什么时候在 PHP Mysqli 中使用准备好的语句?- 用户表单搜索输入与选择查询

我试图了解何时应该在 php/mysqli 中使用准备好的语句。每个 php/mysqli 查询都应该使用准备好的语句还是只使用涉及用户输入的查询和实例……例如要求用户输入数据以在数据库中搜索的 html 表单?


我正在将旧的 php5/mysql 代码迁移到 php7/mysqli。我有许多查询 mysql 数据库的 php 文件。如果我需要为连接到 mysql db 的每个 php 文件使用准备好的语句,我想澄清一下……例如,通过“php require”引用的 php 文件并包含简单的 sql select 语句来呈现图像和指向 html 的链接页?


<?php


//establish connection


$con = new mysqli('localhost','uid','pw','db');


//check connection


if ($con->connect_error) {

die("Connection failed: " . $con->connect_error);  

}


//search variable that stores user input


$search = "%{$_POST['search']}%";


//prepare, bind and fetch


$stmt = $con->prepare("SELECT image, caption FROM `tblimages`

WHERE catid = 3 AND caption LIKE ? order by caption ASC");

$stmt->bind_param("s", $search);

$stmt->execute();

$stmt->bind_result($image,$caption);


while ($stmt->fetch()) {

echo "{$image} <br> {$caption} <br>";    

}


$stmt->close();


//close database connection


mysqli_close($con);


?>

上面的代码有效并且是我第一次使用准备好的语句。它从表单(空白框输入搜索词 - POST)获取用户输入并搜索 db ... 然后将结果呈现到 html 页面。这似乎是准备好的语句的合乎逻辑的用法。但是...我有其他 php 文件,其中用户从表单中的下拉框中选择数据以呈现结果(用户不会像上面那样将数据输入到搜索框中)。我是否也为该实例使用准备好的语句?另外,我是否对通过“php require”引用的 php 文件使用准备好的语句,并包含简单的 sql select 语句来呈现图像和指向 html 页面的链接?我还没有找到使用准备好的语句来防止 sql 注入的特定实例的说明。欢迎任何澄清或参考。


Qyouu
浏览 140回答 2
2回答

扬帆大鱼

这是 MySQLi 准备好的语句在 PHP 中的工作方式:准备一个以空值作为占位符的 SQL 查询(每个值都有一个问号)。通过说明每个变量及其类型,将变量绑定到占位符。执行查询。允许的四种变量类型:i - 整数d - 双s - 字符串b - 斑点准备好的语句,顾名思义,是一种准备 MySQL 调用的方法,而不存储变量。你告诉它变量最终会去那里——只是还没有。演示它的最佳方法是通过示例。$stmt = $mysqli->prepare("SELECT * FROM myTable WHERE name = ? AND age = ?");$stmt->bind_param("si", $_POST['name'], $_POST['age']);$stmt->execute();//fetching result would go here, but will be covered later$stmt->close();如果您以前从未见过准备好的语句,这可能看起来有点奇怪。基本上发生的事情是您正在为 SQL 语句的内容创建模板。在本例中,我们从 myTable 中选择所有内容,其中 name 和 age 等于 ?。问号只是值的位置的占位符。bind_param() 方法是您将变量附加到准备好的模板中的虚拟值的地方。注意变量前的引号中有两个字母。这告诉数据库变量类型。s 指定 name 将是一个字符串值,而 i 强制 age 是一个整数。这正是我没有在名称的问号周围添加引号的原因,就像我通常为 SQL 调用中的字符串所做的那样。您可能认为我只是忘记了,但事实是根本没有必要(事实上,如果您在 ? 周围加上引号,它实际上将不起作用,因为它将被视为字符串文字,而不是一个虚拟占位符。)。当您调用 bind_param() 时,您已经告诉它它将是一个字符串文字,因此即使恶意用户尝试将 SQL 插入到您的用户输入中,它仍将被视为字符串。$stmt->execute() 然后实际运行代码;最后一行只是关闭准备好的语句。我们将在 Select 部分介绍获取结果。
随时随地看视频慕课网APP
我要回答