引言:为什么PHP对新手如此危险?
PHP仍然是Web开发中最流行的语言之一,但其低入门门槛常常导致不良习惯的形成。受简单语法鼓舞的初学者开发者,常常忘记安全性、性能和现代标准。在本文中,我们将分析PHP初学者开发者的顶级错误,这些错误可能使您的代码成为维护的噩梦和攻击的漏洞。
我们不会仅仅列出问题——您将看到带有错误的PHP代码示例及其修正版本。这将帮助您立即应用正确的实践。
1. 忽视安全性:SQL注入和XSS
最关键的错误是信任用户数据。初学者经常将变量直接插入SQL查询或未经过滤就输出到页面。
错误:SQL查询中的字符串拼接
经典的漏洞示例:
// 错误:存在SQL注入漏洞
$id = $_GET['id'];
$query = "SELECT * FROM users WHERE id = $id";
$result = mysqli_query($link, $query);
攻击者可以传入?id=1 OR 1=1并获取表中的所有数据。
解决方案:预处理语句 (PDO)
使用PDO或带预处理语句的mysqli:
// 正确:使用PDO预处理语句
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => $_GET['id']]);
$result = $stmt->fetchAll();
错误:未转义的数据输出 (XSS)
如果您直接输出数据库或$_GET中的数据,您将面临XSS攻击的风险:
// 错误:存在XSS漏洞
echo "你好, " . $_GET['name'];
解决方案:htmlspecialchars
始终转义输出:
// 正确:HTML转义
echo "你好, " . htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');
2. 使用过时的结构和函数
许多10年前的教程教人使用mysql_*函数或短标签。这不仅不安全,而且可能无法在现代主机上运行。
错误:mysql_* 函数
// 错误:过时的扩展
$link = mysql_connect('localhost', 'user', 'pass');
mysql_select_db('test', $link);
该扩展已从PHP 7中移除,代码会直接报错崩溃。
解决方案:迁移到PDO或MySQLi
// 正确:PDO是现代且安全的方法
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
错误:短标签
// 错误:可能在php.ini中被禁用
<? echo "Hello"; ?>
解决方案:仅使用完整标签
// 正确:始终使用 <?php
<?php echo "Hello"; ?>
3. 表单和数据处理不当
初学者开发者经常忘记检查表单是否已提交,并使用$_REQUEST而不是特定的超全局数组。
错误:缺少提交方法检查
// 错误:即使在GET请求时也会执行代码
$name = $_POST['name'];
// ... 处理
解决方案:检查REQUEST_METHOD
// 正确:检查表单是否已提交
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = $_POST['name'] ?? '';
// ... 验证和处理
}
错误:使用$_REQUEST
超全局数组$_REQUEST合并了GET, PO