PHP 2025中的new self与new static:如何选择

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为何SQL注入在2025年依然严峻?



想象一下:你用PHP搭建了一个炫酷的网站,添加了反馈表单和商品搜索功能,一周后却发现攻击者已窃取了整个客户数据库。这听起来像是2010年代的恐怖故事?遗憾的是,根据OWASP统计,SQL注入仍然位列最危险的三大Web应用程序漏洞之一。没错,在2025年,开发者们依然在犯这个错误。



Stack Overflow上关于"如何在PHP中防止SQL注入?"的问题已获得数千次浏览和数百条回答。但问题不在于信息匮乏——而是许多人仍在沿用过时的方法,比如mysql_*函数(早在PHP 7.0中就被移除),或者天真地把mysqli_real_escape_string()当作万能灵药。



本文将详细剖析2025年PHP防范SQL注入的最佳实践。你将了解为什么预处理语句是行业标准,如何正确使用PDO和mysqli,以及经验不足的开发者还会遇到哪些陷阱。开始吧!



通俗解释:什么是SQL注入?



SQL注入是一种攻击方式,攻击者通过用户输入(表单、URL、Cookie)将恶意SQL代码"注入"到查询中。黑客不必简单传递用户名,而是可以发送:' OR '1'='1——从而获取所有数据。



以下是一个经典的漏洞代码示例:



// 切勿这样做!$username = $_POST['username'];$password = $_POST['password'];$query = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";$result = mysqli_query($conn, $query);


如果攻击者在用户名字段中输入:admin' --,查询语句将变成:



SELECT * FROM users WHERE username = 'admin' --' AND password = '...'


--之后的内容全部成为注释。身份验证被绕过。数据库就此失守。你好,数据泄露!



方法一(也是最重要的):预处理语句



在2025年,这是唯一推荐的防范SQL注入方法。预处理语句将SQL逻辑与数据分离。你先告诉数据库:"这是查询模板,这里是变量位置",然后单独传递数据。数据库会自动转义所有需要转义的内容。



选项A:PDO(PHP数据对象)——现代标准



PDO支持12种不同的数据库管理系统(MySQL、PostgreSQL、SQLite等)。如果你在2025年编写新项目,请使用PDO。



<?php// 通过PDO连接数据库$dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8mb4';$user = 'root';$password = '';

try { $pdo = new PDO($dsn, $user, $password); // 重要:出错时抛出异常 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);} catch (PDOException $e) { die('连接错误:' . $e->getMessage());}

// 使用命名占位符的预处理语句$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email AND status = :status');$stmt->execute([ ':email' => $_POST['email'], ':status' => 'active']);$user = $stmt->fetch(PDO::FETCH_ASSOC);

// 使用位置占位符(?)的替代写法$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ? AND status = ?');$stmt->execute([$_POST['email'], 'active']);$user = $stmt->fetch();?>


为什么这样安全?因为数据从未被直接插入到SQL字符串中。即使用户传递了' OR '1'='1,PDO也会将其作为字符串字面量处理,数据库会将其精确地视为字符串,而不是SQL命令的一部分。



选项B:MySQLi(MySQL改进版)

博客

书籍推荐