You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用mysqli_real_escape_string能否防范搜索表单SQL注入?代码求助

嘿,刚入门PHP就关注到SQL注入的问题,这意识真的很棒!先直接回答你的问题:mysqli_real_escape_string确实能在一定程度上防范SQL注入,但它不是最稳妥的方案,而且你的代码里还有不少需要调整的细节,咱们一步步拆解来看:

一、关于mysqli_real_escape_string的有效性

它对字符串类型的用户输入是有效的,但有两个关键前提:

  1. 你必须正确设置数据库连接的字符集(这点你的代码里漏掉了,后面会说),否则转义可能失效,依然存在注入风险;
  2. 它只适用于字符串参数,如果是数字类型的参数,转义逻辑就不适用了。

更推荐的方案是预处理语句(Prepared Statements)——它从根本上把SQL逻辑和用户输入分开,不需要手动转义,安全性更高,后面我会给你示例代码。

二、你的代码存在的问题

先把你的代码格式化后,逐个指出问题:

1. index.php里的问题

  • 重复执行数据库查询:你一开始执行了$sql = "SELECT * FROM anime"; $result = mysqli_query($conn, $sql); $queryresult = mysqli_num_rows($result);,随后又调用$anime = query("SELECT * FROM anime");,这完全是重复查询,浪费数据库资源,删掉前3行即可;
  • 未处理用户输入的空值:如果用户提交空的搜索框,$_GET['s']存在但为空,会导致查询LIKE '%%'返回所有数据,应该先判断输入是否非空;
  • 输出未做XSS防护:直接echo $a['Judul']会有XSS风险(比如标题里包含<script>标签的话会被执行),需要用htmlspecialchars()转义输出;
  • 未处理LIKE通配符:用户输入%或_这类LIKE通配符时,会返回所有数据或匹配意外结果,需要转义这些字符;
  • 缺少查询结果为空的提示:如果搜索不到内容,页面会空着,体验不好。

2. connect.php里的问题

  • 没有数据库连接错误检查:mysqli_connect可能失败(比如密码错误、数据库不存在),需要添加错误判断;
  • 未设置数据库字符集:必须设置字符集为utf8mb4(支持所有Unicode字符,包括emoji),否则mysqli_real_escape_string可能失效;
  • query函数缺少错误处理:如果SQL语句出错,mysqli_query会返回false,后续mysqli_fetch_assoc会报错,需要添加错误捕获。

三、改进后的代码示例

改进版connect.php

<?php
$server = "localhost";
$username = "root";
$password = "";
$databasename = "anime";

// 连接数据库并检查连接错误
$conn = mysqli_connect($server, $username, $password, $databasename);
if (!$conn) {
    die("数据库连接失败: " . mysqli_connect_error());
}

// 设置字符集为utf8mb4,确保转义有效且支持全字符
mysqli_set_charset($conn, 'utf8mb4');

function query($query) {
    global $conn;
    $result = mysqli_query($conn, $query);
    // 检查查询是否成功
    if (!$result) {
        die("查询错误: " . mysqli_error($conn));
        // 生产环境建议不要直接输出错误,改为记录日志
        // error_log("SQL Error: " . mysqli_error($conn));
        // die("服务器出错,请稍后重试");
    }
    $rows = [];
    while( $row = mysqli_fetch_assoc($result) ) {
        $rows[] = $row;
    }
    return $rows;
}

改进版index.php(保留转义方式,修复所有问题)

<?php
include 'connect.php';

$anime = [];
// 检查搜索参数是否存在且非空
if (isset($_GET['s']) && !empty(trim($_GET['s']))) {
    $search = mysqli_real_escape_string($conn, trim($_GET['s']));
    // 转义LIKE通配符,避免用户输入%/_干扰搜索结果
    $search = str_replace(['%', '_'], ['\%', '\_'], $search);
    $sql = "SELECT * FROM anime WHERE Judul LIKE '%$search%'";
    $anime = query($sql);
} else {
    // 无搜索时获取所有数据
    $anime = query("SELECT * FROM anime");
}
?>
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
    <meta charset="utf-8">
    <title>Anime 搜索</title>
</head>
<body>
    <form action="" method="get">
        <!-- 保留用户输入的搜索关键词,同时转义防止XSS -->
        <input type="text" name="s" placeholder="输入关键词搜索" value="<?php echo isset($_GET['s']) ? htmlspecialchars($_GET['s']) : ''; ?>">
        <button type="submit">搜索</button>
    </form>

    <?php if (!empty($anime)) : ?>
        <ul>
            <?php foreach ($anime as $a) : ?>
                <!-- 转义输出,防止XSS -->
                <li><?php echo htmlspecialchars($a['Judul']); ?></li>
            <?php endforeach ; ?>
        </ul>
    <?php else : ?>
        <p>没有找到符合条件的内容</p>
    <?php endif; ?>
</body>
</html>

更安全的预处理语句版本(推荐)

把index.php里的搜索逻辑改成下面这样,不需要手动转义,从根源避免SQL注入:

<?php
include 'connect.php';

$anime = [];
if (isset($_GET['s']) && !empty(trim($_GET['s']))) {
    $searchPattern = '%' . trim($_GET['s']) . '%';
    // 初始化预处理语句
    $stmt = mysqli_prepare($conn, "SELECT * FROM anime WHERE Judul LIKE ?");
    // 绑定参数("s"表示字符串类型)
    mysqli_stmt_bind_param($stmt, "s", $searchPattern);
    // 执行语句
    mysqli_stmt_execute($stmt);
    // 获取结果集
    $result = mysqli_stmt_get_result($stmt);
    // 提取数据
    while ($row = mysqli_fetch_assoc($result)) {
        $anime[] = $row;
    }
    // 关闭语句
    mysqli_stmt_close($stmt);
} else {
    $anime = query("SELECT * FROM anime");
}
?>

总结

  • mysqli_real_escape_string在正确配置字符集的情况下对字符串参数有效,但预处理语句是更可靠的防注入方案;
  • 你的代码主要需要补充错误处理、字符集设置、XSS防护,同时优化查询逻辑。

内容的提问来源于stack exchange,提问作者Variel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 13:42:51