You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用sqlsrv_prepare函数?SQL Server网站搜索防注入

手把手教你用sqlsrv_prepare实现安全的搜索功能

嘿,我懂你这种看着文档却摸不着头脑的感觉!别慌,结合你的搜索场景,我一步步把sqlsrv_prepare的用法讲透,保证你看完就能上手,还能彻底防SQL注入。

首先得搞明白,sqlsrv_prepare的核心就是把SQL结构和参数彻底分开——数据库会先把你的SQL模板(比如带占位符的查询语句)预编译好,再把参数塞进去执行,这样参数里的特殊字符(比如'、--这些注入常用的)就只会被当成普通文本,根本不会被解析成SQL指令,从根源上杜绝注入风险。

接下来直接上适配你场景的完整代码,每一步都给你标清楚:

第一步:先搞定数据库连接

// 替换成你的数据库配置
$serverName = "localhost"; // 或者你的SQL Server地址
$connectionOptions = [
    "Database" => "你的数据库名",
    "Uid" => "数据库用户名",
    "PWD" => "数据库密码"
];

// 建立连接,失败就输出错误
$conn = sqlsrv_connect($serverName, $connectionOptions);
if (!$conn) {
    die("数据库连接炸了:" . print_r(sqlsrv_errors(), true));
}

第二步:处理搜索参数

这里要注意,不要直接把用户输入的内容拼进SQL,我们把%加到参数值里,而不是SQL语句中:

// 获取POST过来的搜索关键词,先做基本的空值处理和去空格
$search = isset($_POST["search"]) ? trim($_POST["search"]) : "";
// 把通配符%和关键词拼接,用于LIKE查询
$searchParam = "%$search%";

第三步:预编译SQL语句(核心步骤!)

sqlsrv用?作为参数占位符,顺序一定要和后面的参数数组对应:

// 写SQL模板,用?代替要传入的参数
$sql = "SELECT * FROM 你的表名 WHERE 要搜索的字段名 LIKE ?";

// 定义参数数组,每个元素是一个子数组,指定参数值和类型
// SQLSRV_PARAM_IN表示这是输入参数(给数据库传值)
$params = [
    [$searchParam, SQLSRV_PARAM_IN]
    // 如果需要更严谨,可以指定数据类型,比如字符串类型:
    // [$searchParam, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING, SQLSRV_SQLTYPE_VARCHAR(255)]
];

// 执行预编译,得到语句对象
$stmt = sqlsrv_prepare($conn, $sql, $params);
if (!$stmt) {
    die("预编译失败:" . print_r(sqlsrv_errors(), true));
}

第四步:执行预编译好的语句并处理结果

// 执行语句
if (sqlsrv_execute($stmt)) {
    // 循环读取结果,SQLSRV_FETCH_ASSOC表示返回关联数组(用字段名当键)
    while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
        // 这里替换成你要输出的字段,比如:
        echo "ID: {$row['id']} | 标题: {$row['title']}<br>";
    }
} else {
    die("查询执行失败:" . print_r(sqlsrv_errors(), true));
}

第五步:收尾工作,释放资源

// 释放语句资源
sqlsrv_free_stmt($stmt);
// 关闭数据库连接
sqlsrv_close($conn);

敲黑板划重点!这些坑千万别踩:

  • 占位符只能用?:sqlsrv不支持命名占位符(比如:search),参数数组的顺序必须和SQL里的?完全对应,错一个位置就会出问题。
  • %一定要加在参数里:绝对不能写成LIKE '%?%',这样数据库会把?当成字符串的一部分,参数绑定直接失效,等于白做了防注入。
  • 一定要检查错误:sqlsrv_errors()能返回详细的错误信息,调试的时候别嫌麻烦,加进去能帮你快速定位问题。
  • 参数类型可选但建议加:如果你的字段是固定类型(比如整数、日期),指定参数类型能避免类型转换导致的奇怪问题,让代码更健壮。

最后再补充一句,sqlsrv_prepare和sqlsrv_query的区别:如果只是执行一次查询,用sqlsrv_query也能实现参数绑定,但sqlsrv_prepare适合需要重复执行同一条SQL(比如批量插入)的场景,预编译一次后多次执行,效率更高。而你的搜索场景用它,核心目的就是安全防注入,完全没问题。

内容的提问来源于stack exchange,提问作者TakeDown

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:08:14