PHP增删改查怎么防止SQL注入_php防注入技巧【安全】

防止SQL注入应优先使用预处理语句(PDO或MySQLi),辅以输入验证、禁用危险函数、最小权限数据库账户配置。

如果在PHP中执行数据库增删改查操作时直接拼接用户输入的数据,则极易导致SQL注入攻击。以下是防止SQL注入的多种安全实践方法:

一、使用预处理语句(PDO)

预处理语句将SQL逻辑与用户数据分离,数据库驱动会自动对参数进行转义和类型绑定,从根本上杜绝SQL注入可能。

1、创建PDO连接并设置错误模式为异常模式:setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)

2、编写带占位符的SQL语句,例如:INSERT INTO users (name, email) VALUES (?, ?)

3、调用prepare()方法获取PDOStatement对象。

4、调用execute()方法传入参数数组,如['张三', 'zhang@example.com']

5、查询操作同样适用,fetch()fetchAll()获取结果前已确保参数安全。

二、使用预处理语句(MySQLi面向对象方式)

MySQLi也支持预处理机制,通过绑定参数实现数据与SQL结构隔离,避免字符串拼接带来的风险。

1、使用new mysqli()建立连接,并确认connect_error为null。

2、调用prepare()方法传入含问号占位符的SQL,例如:SELECT * FROM products WHERE id = ? AND status = ?

3、使用bind_param()绑定变量,第一个参数指定类型(如"is"表示整型+字符串),后续为对应变量。

4、执行execute()后,通过get_result()获取结果集。

5、更新、删除操作同理,仅需替换SQL语句类型与绑定参数即可。

三、严格过滤与验证输入数据

在SQL执行前对用户输入进行类型校验、长度限制和内容白名单检查,可作为预处理之外的补充防御层。

1、对ID类参数使用filter_var($id, FILTER_VALIDATE_INT)验证是否为合法整数。

2、对邮箱字段使用filter_var($email, FILTER_VALIDATE_EMAIL)进行格式校验。

3、对用户名等字符串字段使用strlen()限制最大长度,并用ctype_alnum()或正则/^[a-zA-Z0-9_\x{4e00}-\x{9fa5}]+$/u限定字符范围。

4、对下拉菜单、单选按钮等可控值,采用in_array($input, $allowed_values, true)进行白名单比对。

5、拒绝处理空值、全空格、仅特殊符号等明显异常输入,直接中断后续数据库操作。

四、禁用危险函数与动态拼接

避免使用已知存在注入风险的函数组合,切断SQL注入的常见入口路径。

1、绝对禁止使用mysql_query()及其相关函数(该扩展已被PHP 7.0废弃且无预处理支持)。

2、禁止将用户输入直接嵌入SQL字符串,如"SELECT * FROM table WHERE name = '$name'"

3、禁用eval()create_function()assert()等可执行动态代码的函数。

4、关闭magic_quotes_gpc(PHP 5.4+已移除),因其自动转义不可靠且干扰预处理逻辑。

5、不依赖客户端JavaScript验证,所有校验必须在服务端重复执行。

五、最小权限数据库账户配置

即使代码存在疏漏,受限的数据库账户权限也能大幅降低SQL注入成功后的危害程度。

1、为Web应用单独创建数据库用户,避免使用root或具有ALL PRIVILEGES的账号。

2、仅授予当前业务必需的权限,例如只读页面仅分配SELECT,后台管理才附加INSERT/UPDATE/DELETE

3、禁止授予FILEEXECUTEPROCESSSUPER等高危权限。

4、限制用户可访问的数据库范围,使用GRANT ... ON database_name.* TO 'user'@'host'精确指定库名。

5、生产环境数据库监听地址应绑定内网IP,禁止绑定0.0.0.0或暴露于公网。