SQL注入是PHP开发中常见的安全威胁,攻击者通过构造恶意输入篡改SQL语句逻辑,窃取或破坏数据库数据。其核心原理在于未对用户输入做严格过滤,直接拼接SQL语句执行。例如,用户输入`1′ OR ‘1’=’1`作为ID参数时,若未转义,可能导致查询返回全部数据。防御SQL注入的关键在于切断用户输入与SQL语句的直接关联。
预处理语句(Prepared Statements)是防御SQL注入的黄金标准。PHP中可通过PDO或MySQLi扩展实现。以PDO为例,先定义带占位符的SQL模板(如`SELECT FROM users WHERE username = :username`),再通过`bindParam()`绑定变量。占位符确保输入被当作数据而非代码处理,即使输入包含特殊字符也会被自动转义。例如:
“`php
$pdo = new PDO(‘mysql:host=localhost;dbname=test’, ‘user’, ‘pass’);
$stmt = $pdo->prepare(‘SELECT FROM users WHERE id = :id’);
$stmt->bindParam(‘:id’, $_GET[‘id’], PDO::PARAM_INT);

AI生成的趋势图,仅供参考
$stmt->execute();
“`
若因特殊原因无法使用预处理语句,必须对动态输入进行严格过滤。使用`mysqli_real_escape_string()`函数转义特殊字符(如单引号、双引号),但需注意连接对象需为有效MySQLi实例。更推荐使用白名单机制,例如验证数字ID时强制转换为整数:`$id = (int)$_GET[‘id’];`,或使用正则表达式限制输入格式(如邮箱、手机号校验)。
存储过程和ORM框架也能间接防御注入。存储过程将SQL逻辑封装在数据库层,参数通过绑定方式传递;ORM(如Eloquent、Doctrine)会自动处理参数转义,减少手动拼接SQL的风险。但需注意,错误使用ORM的`raw()`方法或存储过程内拼接SQL仍可能导致漏洞。
安全开发需贯穿整个流程。启用错误报告时避免暴露数据库结构细节;定期更新PHP和数据库版本修复已知漏洞;使用最小权限原则配置数据库账户,避免使用root账户。代码审计阶段可通过静态分析工具(如PHPStan、SonarQube)检测潜在注入点,或手动检查所有`query()`、`exec()`等数据库操作是否使用预处理。