PHP 字符串转义、转码与特殊字符处理实战指南

Owen
Owen
发布时间:2026-10-13| 5人浏览过
原创

在处理用户输入和数据库交互时,正确的字符串转义与编码是防止 SQL 注入和 XSS 攻击的关键。本文梳理了 PHP 中常用的转义函数(如 addslashes、htmlspecialchars)及其历史配置项,提供数组递归转义的代码实现,并详细解析 \n、\0 等特殊字符的处理逻辑。

核心转义函数对比与应用

PHP 提供了多种针对不同场景的转义机制。理解它们的区别能避免常见安全漏洞。

第一步:识别环境与基础转义

目的:了解全局配置对转义的影响,掌握基础的字符过滤函数。

  • magic_quotes_gpc:此配置曾自动为 GET、POST、COOKIE 数据添加反斜杠。但在 PHP 5.3.0+ 版本中已废弃,PHP 7 已完全移除。因此,现代开发不应依赖它,而应手动处理。
  • addslashes():在预定义字符前添加反斜杠。预定义字符包括单引号 (')、双引号 (")、反斜线 (\\) 与 NUL 字符。注意:它并非通用的 SQL 转义函数,因为它不区分数据库字符集。
  • stripslashes():删除由 addslashes() 添加的反斜杠。
复制代码
// 如果 magic_quotes_gpc 未开启,手动进行递归转义
if(!get_magic_quotes_gpc()) {
    $_GET = daddslashes($_GET);
    $_POST = daddslashes($_POST);
    $_COOKIE = daddslashes($_COOKIE);
}

function daddslashes($string, $force = 1) {
    if(is_array($string)) {
        foreach($string as $key => $val) {
            unset($string[$key]);
            $string[addslashes($key)] = daddslashes($val, $force);
        }
    } else {
        $string = addslashes($string);
    }
    return $string;
}

第二步:针对 SQL 查询的转义

目的:安全地将数据插入数据库。

  • mysql_escape_string():转义 SQL 语句中的特殊字符,包括 \x00、\n、\r、\\、'、"、\x1a。
    注意:mysql_* 系列函数已在 PHP 5.5 中被废弃,并在 PHP 7.0 中移除。强烈建议迁移至 mysqli_real_escape_string() 或更推荐的 PDO 预处理语句(Prepared Statements)。
  • addcslashes():C 语言风格的转义。当对字符 0, a, b, f, n, r, t, v 转义时,会转换为 \0, \a 等格式。主要用于控制字符的特定表示。

第三步:防止 XSS 的 HTML 实体编码

目的:在输出到浏览器前,将可能被视为 HTML 标签的字符转为实体。

  • htmlspecialchars():将预定义的 HTML 特殊字符转换为实体:
    & → &
    " → "
    ' → &#039 (若 flags 包含 ENT_QUOTES)
    < → &lt;
    > → &gt;
  • htmlentities():转换所有 HTML 实体,不仅是预定义的几个。
  • 逆向操作:htmlspecialchars_decode() 和 html_entity_decode() 用于将实体还原为原始字符。

PHP 字符串中的特殊字符与转义序列

除了内置函数,理解 PHP 字符串字面量本身支持的转义序列对于调试和处理二进制数据至关重要。

第四步:单引号与双引号字符串的差异

  • 单引号 (''):
    支持 \' 和 \\。
    其他转义序列如 \n 会被原样输出,不会解释为换行符。
  • 双引号 ("):
    支持更多转义序列:
    - \n: 换行 (LF)
    - \r: 回车 (CR)
    - \t: 水平制表符
    - \\: 反斜线
    - \$: 美元符号
    - \": 双引号
    - \[0-7]{1,3}: 八进制 ASCII 码
    - \x[0-9A-Fa-f]{1,2}: 十六进制 ASCII 码

第五步:特殊字符的检测与替换实战

目的:处理包含空字节或其他控制字符的脏数据。

1. \0 (NUL 字符) 处理

复制代码
$str = "ffff\0ffff";
echo strlen($str); // 输出: 9 (包含 \0)
echo "\n";

// 替换 \0 为空字符串
$str = str_replace("\x0", "", $str);
// 或者使用 octal: str_replace("\0", "", $str);
// 或者使用 chr: str_replace(chr(0), "", $str);
echo strlen($str); // 输出: 8

2. 八进制 ASCII 码序列

在双引号字符串中,符合 [0-7]{1,3} 模式的序列会被解析为对应的 ASCII 字符。不符合范围的数字(如 \8)会被保留原样(即 \ 和 8)。

复制代码
$str = "\0\01\02\3\7\10\011\08\8";
// \8 未被识别为八进制,变为 \\8 (ASCII 92 和 56)
// 最终长度: 11

3. 十六进制 ASCII 码序列

\x 后跟 1-2 位十六进制数会被解析。

复制代码
$str = "\x0\x1\x2\x3\x7\x8\x9\x10\x11\xff";
// 输出各字符的 ord 值分别为: 0, 1, 2, 3, 7, 8, 9, 16, 17, 255

总结与最佳实践

  1. 弃用旧配置:不再使用 set_magic_quotes_runtime(),应在代码初始化或服务器配置中确保其为关闭状态。
  2. SQL 安全:放弃 mysql_escape_string,优先使用 PDO 预处理语句。若必须使用原生函数,请使用 mysqli_real_escape_string()。
  3. XSS 防护:在输出 HTML 之前,务必使用 htmlspecialchars($str, ENT_QUOTES | ENT_HTML5, 'UTF-8') 进行编码。
  4. 递归处理:对于数组形式的输入(如 POST 数据),需编写递归函数对键值和值同时进行转义。
以上就是PHP字符转义相关函数的详细内容,更多关于PHP安全防护、字符串处理的资料请关注本站其它相关文章!
相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。