str_replace支持数组参数批量替换,比循环调用更高效且避免二次污染;需注意搜索与替换数组等长、顺序影响结果;复杂场景应选preg_replace;html内容需先反转义再替换。

str_replace 一次调用就能批量替换,别写循环
PHP 的 str_replace 原生支持数组参数,传入多个搜索项和替换项,内部自动遍历处理。手写 foreach 调用 str_replace 不仅慢,还可能因顺序导致二次污染(比如把刚替好的内容又替了一遍)。
常见错误现象:str_replace(['a', 'ab'], ['X', 'Y'], 'ab') 返回 'Yb' 而不是 'Y' —— 因为 'a' 先被替成 'X',剩下 'Xb','ab' 已不存在,无法再匹配。顺序和长度都影响结果。
- 搜索数组和替换数组必须等长;若替换数组更短,末尾缺失项视作空字符串
'' - 第三个参数(待处理字符串)可以是字符串,也可以是数组,返回值类型与之保持一致
- 不区分大小写?用
str_ireplace,它和str_replace参数结构完全一样
想按顺序逐个替换且避免干扰,用 preg_replace + 数组
当必须保证替换顺序、且前一步的输出不能成为后一步的输入源(比如防止 a → x 后,x 又被误匹配进下一条规则),str_replace 的批量模式就不合适了。这时该用 preg_replace 配合键值对数组,一次性编译正则、原子化执行。
使用场景:模板变量替换({name}, {email})、日志脱敏(先掩码手机号,再掩码身份证号,二者模式不重叠)。
立即学习“PHP免费学习笔记(深入)”;
- 写法:
preg_replace(array_keys($map), array_values($map), $text),其中$map是['/{name}/' => $name, '/{email}/' => $email]这样的关联数组 - 注意所有 key 必须是合法正则模式,含分隔符(如
/)和转义;简单字面量推荐用preg_quote($str, '/')处理 - 性能上,少量替换
str_replace更快;几十个以上规则、需精确控制顺序时,preg_replace数组版更稳
替换结果含 HTML 标签?先 decode 再 replace,否则会出错
从表单或数据库读出的字符串如果经过 htmlspecialchars 处理过(比如 <p>hello</p>),直接对 <p></p> 执行 str_replace 是找不到的——你实际操作的是字符实体,不是标签本身。
常见错误现象:想把文本中的 foo 替成 bar,但源字符串是 <div>foo</div>,结果什么也没换到,还以为函数失效。
- 先判断是否需要反转义:
htmlspecialchars_decode($text, ENT_QUOTES),再替换,最后按需重新编码(如果要输出到页面) - 如果目标就是操作 HTML 源码字符串(比如做模板预处理),那得确保搜索项也用实体形式,比如用
'<span>'而非'<span>'</span> - 更安全的做法:用 DOM 解析器(如
DOMDocument)处理真实 HTML 结构,str_replace只用于纯文本上下文
大数据量替换卡顿?检查是否误用了递归或嵌套循环
有人把 str_replace 放在多层 foreach 里,或者对大数组每个元素都调用一次,看似逻辑清楚,实则时间复杂度爆炸。10 万行文本 × 50 个关键词 = 500 万次函数调用,PHP 默认配置下很容易超时或内存溢出。
性能影响比想象中大:每次 str_replace 都要扫描整个字符串,重复扫描成本极高;而批量传数组是一次性建索引、单趟扫描完成。
- 把关键词和替换值预先整理成两个索引对齐的数组,统一传给
str_replace - 如果关键词有公共前缀(比如全是
user_*),考虑用正则 + 回调(preg_replace_callback)减少匹配次数 - 实在要循环,至少把
str_replace移到最内层循环之外,避免重复构造参数数组











