php代码示例如何防止sql注入_php防sql注入代码示例【示例】
发布时间 - 2026-01-29 00:00:00 点击率:次使用 mysqli::prepare() + bind_param() 或 PDO::prepare() + execute()(禁用模拟预处理)是最直接有效的防SQL注入方式,通过预处理机制彻底分离SQL结构与数据,从执行层面杜绝注入可能。
用 mysqli::prepare() + bind_param() 是最直接有效的防注入方式
PHP 原生 MySQLi 扩展的预处理语句能彻底分离 SQL 结构与数据,让数据库引擎在解析阶段就拒绝恶意拼接。不是“过滤输入”,而是从执行机制上杜绝注入可能。
常见错误是只做 mysqli_real_escape_string() 或简单 str_replace(),这些对绕过型 payload(比如宽字节、十六进制编码、注释符组合)完全无效。
- 必须使用
prepare()创建语句对象,再用bind_param()绑定变量,不能把变量直接拼进 SQL 字符串 - 参数类型标识要准确:
"s"(字符串)、"i"(整数)、"d"(浮点)、"b"(BLOB),类型不匹配可能导致绑定失败或隐式转换漏洞 - 注意连接字符集:确保
mysqli_set_charset($conn, 'utf8mb4')已调用,否则宽字节注入仍可能发生
$stmt = $mysqli->prepare("SELECT * FROM users WHERE username = ? AND status = ?");
$stmt->bind_param("si", $username, $status);
$username = $_GET['user'] ?? '';
$status = (int)($_GET['active'] ?? 1);
$stmt->execute();
$result = $stmt->get_result();
PDO 的 prepare() + execute() 更灵活但要注意默认模式
PDO 默认启用模拟预处理(PDO::ATTR_EMULATE_PREPARES = true),此时 SQL 并未真正发给 MySQL,而是由 PHP 模拟参数替换——这会退化为字符串拼接,失去防护能力。
必须显式关闭模拟,并确认驱动支持原生预处理:
- 初始化时设置
PDO::ATTR_EMULATE_PREPARES => false - 检查
$pdo->getAttribute(PDO::ATTR_CLIENT_VERSION)和 MySQL 版本(5.1.17+ 支持完整原生预处理) - 命名参数(
:name)比问号占位符更易读,但底层安全等级一致
$pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_E
RRMODE => PDO::ERRMODE_EXCEPTION
]);
$stmt = $pdo->prepare("INSERT INTO logs (ip, action) VALUES (:ip, :action)");
$stmt->execute(['ip' => $_SERVER['REMOTE_ADDR'], 'action' => 'login']);
不要用 mysql_*() 函数,它们已废弃且无法预处理
PHP 7.0 起已移除所有 mysql_connect()、mysql_query() 等函数,任何还在用它们的代码不仅有注入风险,还会直接报致命错误。
即使加了 mysql_real_escape_string(),也挡不住如下攻击:
-
admin' --(注释掉后续校验) -
admin' OR SLEEP(5) #(延时盲注) -
1' UNION SELECT password FROM users #(联合查询)
迁移路径只有两条:改用 MySQLi 或 PDO,没有中间选项。
过滤函数如 htmlspecialchars() 不解决 SQL 注入
这个函数只用于输出 HTML 上下文,防止 XSS,对 SQL 查询毫无作用。把它用在查询前,等于给子弹套了个纸盒子——看起来像防护,实际一打就穿。
典型误用场景:
- 对用户输入先
htmlspecialchars()再拼进 SQL(依然可注入) - 用
intval()处理 ID 但没校验返回值是否为 0(intval('1 OR 1=1')返回 1) - 用正则白名单过滤但遗漏了 Unicode 变体或编码绕过
真正安全的整数处理是:强制类型转换 + 边界校验 + 预处理绑定,三者缺一不可。
# mysql
# php
# word
# html
# 编码
# 字节
# sql注入
# 防止sql注入
# 隐式转换
# lsp
# sql
# xss
# select
# mysqli
# pdo
# 字符串
# union
# 强制类型转换
# 类型转换
# 对象
# 数据库
# 绑定
# 还在
# 浮点
# 是由
# 还会
# 是从
# 把它
# 两条
# 能把
# 再用
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel定时任务怎么设置_Laravel Crontab调度器配置
Laravel事件监听器怎么写_Laravel Event和Listener使用教程
香港服务器网站推广:SEO优化与外贸独立站搭建策略
ChatGPT 4.0官网入口地址 ChatGPT在线体验官网
常州企业网站制作公司,全国继续教育网怎么登录?
黑客如何利用漏洞与弱口令入侵网站服务器?
百度浏览器如何管理插件 百度浏览器插件管理方法
laravel怎么配置Redis作为缓存驱动_laravel Redis缓存配置教程
Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】
免费视频制作网站,更新又快又好的免费电影网站?
韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐
Laravel如何实现用户注册和登录?(Auth脚手架指南)
EditPlus中的正则表达式 实战(1)
JavaScript如何操作视频_媒体API怎么控制播放
Laravel如何为API生成Swagger或OpenAPI文档
免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?
移动端脚本框架Hammer.js
Laravel如何使用Blade模板引擎?(完整语法和示例)
EditPlus 正则表达式 实战(3)
laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法
七夕网站制作视频,七夕大促活动怎么报名?
Windows Hello人脸识别突然无法使用
如何快速查询域名建站关键信息?
Laravel如何实现本地化和多语言支持_Laravel多语言配置与翻译文件管理
Laravel的路由模型绑定怎么用_Laravel Route Model Binding简化控制器逻辑
Swift中循环语句中的转移语句 break 和 continue
如何用IIS7快速搭建并优化网站站点?
简单实现Android文件上传
详解CentOS6.5 安装 MySQL5.1.71的方法
如何选择可靠的免备案建站服务器?
怎么用AI帮你为初创公司进行市场定位分析?
如何在阿里云虚拟服务器快速搭建网站?
高端建站三要素:定制模板、企业官网与响应式设计优化
javascript基于原型链的继承及call和apply函数用法分析
如何在Windows虚拟主机上快速搭建网站?
昵图网官网入口 昵图网素材平台官方入口
历史网站制作软件,华为如何找回被删除的网站?
如何用腾讯建站主机快速创建免费网站?
在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?
智能起名网站制作软件有哪些,制作logo的软件?
如何快速搭建虚拟主机网站?新手必看指南
Google浏览器为什么这么卡 Google浏览器提速优化设置步骤【方法】
Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置
Win11怎么更改系统语言为中文_Windows11安装语言包并设为显示语言
php打包exe后无法访问网络共享_共享权限设置方法【教程】
Laravel怎么使用artisan命令缓存配置和视图
,网页ppt怎么弄成自己的ppt?
uc浏览器二维码扫描入口_uc浏览器扫码功能使用地址
如何在阿里云ECS服务器部署织梦CMS网站?
Laravel怎么进行浏览器测试_Laravel Dusk自动化浏览器测试入门


