← PHP addcslashes()函数:C风格字符串转义教程 PHP bin2hex()函数:字符串与十六进制互转教程 →

PHP addslashes()函数:转义引号与反斜杠的指南

著
原创 2026-10-10 PHP 已有人查阅

一、addslashes()到底做了什么

addslashes()是PHP内置的字符串处理函数,它的作用很单一:在特定字符前加上反斜杠\进行转义。

受影响的字符有四个:

字符 转义后
单引号' \'
双引号" \"
反斜杠\ \\
NUL字节 \0

语法:

string addslashes ( string $str )

参数$str是必须传入的待转义字符串,函数返回转义后的新字符串。

这里有个容易忽略的点:addslashes()不会转义反斜杠本身以外的其他控制字符,也不会处理换行、回车等。它只针对上面列出的四个字符。

二、基础示例:观察转义效果

先看一个直接输出对比的例子。代码号学习编程建议在本地环境实际跑一遍,观察浏览器输出和查看源代码的区别。

<?php
$str = 'What does "WHO" mean?';
echo "原始字符串:" . $str;
echo "<br>";
echo "addslashes 之后:" . addslashes($str);
?>

输出:

原始字符串:What does "WHO" mean?
addslashes 之后:What does \"WHO\" mean?

双引号被加上了反斜杠。再看单引号的情况:

<?php
$str = "Who's the father of PHP?";
echo $str . " —— 直接用于数据库查询存在风险。<br>";
echo addslashes($str) . " —— 经过 addslashes 处理后。";
?>

输出:

Who's the father of PHP? —— 直接用于数据库查询存在风险。
Who\'s the father of PHP? —— 经过 addslashes 处理后。

单引号被转义为\',在旧式的字符串拼接SQL中,这样能避免引号提前闭合。

三、eval()场景下的转义需求

eval()会执行一段PHP代码字符串。如果字符串里含有单引号,直接拼接会导致语法错误。

<?php
$str = "Wow' PHP?";
eval("echo '" . addslashes($str) . "';");
?>

输出:

Wow' PHP?

这里addslashes()的作用是防止$str中的单引号破坏eval中字符串的边界。但说实话,现在PHP开发中eval()本身就应该尽量避免使用,它带来的安全风险远大于便利性。如果确实需要动态执行代码,优先考虑回调函数、策略模式等替代方案。

四、项目中的反思:为什么现在不推荐addslashes()做数据库转义

这是本文最想强调的部分。

很多老教程会告诉你:addslashes()可以让字符串"安全地"用于数据库查询。这个说法在十几年前或许成立,但现在来看是有问题的。

原因一:字符集问题

addslashes()不感知数据库连接的字符集。在GBK等多字节字符集中,某些字符的字节序列可能包含0x5C(反斜杠的ASCII码),addslashes()的转义反而可能被绕过,造成注入漏洞。

原因二:它只转义四个字符

SQL注入的payload不一定依赖单引号或双引号。数字型注入、注释符、UNION查询等场景,addslashes()无能为力。

原因三:预处理语句才是正解

PDO或MySQLi的预处理语句(PreparedStatements)将SQL结构与数据分离,数据库驱动层面处理转义,不依赖开发者手动拼接。这才是现在PHP项目应该采用的方式。

个人踩坑经历:早期做一个小型后台系统时,用addslashes()处理用户输入后拼接SQL,测试阶段没发现问题。上线后遇到一个用户昵称里包含特殊字符组合,配合GBK编码导致转义失效,差点造成数据泄露。从那以后,所有数据库操作一律走PDO预处理,再也没碰过addslashes()做SQL转义。

那addslashes()还有用吗?

有,但场景很窄。比如:

  • 生成某些特定格式的文本文件,需要对引号做转义

  • 旧系统维护,无法立即重构为预处理语句时的临时兼容

  • 配合stripslashes()做简单的字符串往返处理

五、addslashes()与相关函数的配合

stripslashes()是addslashes()的逆操作,去掉字符串中的反斜杠转义。

<?php
$original = "It's a \"test\" string.";
$escaped = addslashes($original);
echo "转义后:" . $escaped . "<br>";
echo "还原后:" . stripslashes($escaped);
?>

输出:

转义后:It\'s a \"test\" string.
还原后:It's a "test" string.

注意:stripslashes()并不是严格可逆的。如果原始字符串中本来就包含反斜杠,经过addslashes()再stripslashes()后,反斜杠的数量可能发生变化。这一点在处理文件路径时要特别小心。

addcslashes()则是更灵活的版本,可以指定要转义的字符范围:

<?php
$str = "Hello, PHP World!";
echo addcslashes($str, 'A..Z');
?>

输出:

\H\e\l\l\o, \P\H\P \W\o\r\l\d!

addcslashes()允许用字符范围指定转义目标,比addslashes()更可控,但也更容易误用。除非有明确需求,否则不建议在常规业务中随意使用。

六、本节课程知识要点

  1. addslashes()转义四个字符:单引号、双引号、反斜杠、NUL字节。

  2. 它不感知字符集,在多字节编码环境下可能失效。

  3. 现在PHP数据库操作应使用PDO或MySQLi的预处理语句,而非addslashes()。

  4. stripslashes()是逆操作,但对含反斜杠的原始字符串不可逆。

  5. addcslashes()提供更灵活的转义范围控制,按需使用。

  6. eval()场景下的转义只是历史用法,现在开发应避免eval()。

七、常见问题

Q:addslashes()和htmlspecialchars()有什么区别?

A:addslashes()用于字符串转义(如SQL拼接、eval),htmlspecialchars()用于HTML实体转义,防止XSS。两者用途不同,不能互相替代。

Q:用了addslashes()是不是就安全了?

A:不是。它只处理四个字符,且不感知字符集。安全防护需要根据具体场景选择正确的方案,数据库用预处理,HTML输出用htmlspecialchars(),URL用urlencode()。

Q:2026年还有必要学addslashes()吗?

A:有必要了解,因为维护旧项目时可能遇到。但新项目不应将其作为数据库转义手段。

addslashes()是一个简单直接的字符串转义函数,在PHP早期被广泛用于SQL拼接场景。随着预处理语句的普及和安全意识的提升,它的数据库转义角色已经退场。理解它的转义规则、局限性以及与现在方案的差异,有助于在维护旧代码和面试中做出准确判断。

写代码时,先问自己:这个转义是为了解决什么问题?数据库、HTML、URL还是文件路径?选对工具,比会用工具更重要。

← PHP addcslashes()函数:C风格字符串转义教程 PHP bin2hex()函数:字符串与十六进制互转教程 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号