
用 strip_tags() 最快,但默认不处理属性和自闭合标签
strip_tags() 是 PHP 内置函数,专为这事设计,性能好、不用装扩展。但它只删标签,不解析 HTML 结构 —— 比如 <img src="x" alt="php怎么过滤html标签 php字符串去除html代码【重点】" > 会被整段干掉,但 <script>alert(1)</script> 里的 JS 代码不会执行,只是文字被留下(除非你同时用了 htmlspecialchars())。
常见错误是以为它能“安全过滤”,结果用户提交 <a href="javascript:alert(1)">点我</a>,strip_tags() 后变成纯文本 点我,看似没问题;但如果后续拼进 HTML 属性里(比如 <div title="'.$str.'">),就可能触发 XSS。
<ul>
<li>只传字符串: <code>strip_tags($html)
strip_tags($html, ['br', 'p', 'strong'])
<hr> 这种写法在旧 PHP 版本里可能被忽略<br>)识别更稳,老版本建议先 str_replace() 统一成 <br> 再处理要真正防 XSS,不能只靠 strip_tags()
它不转义引号、不处理属性里的 JS 协议、不清理 CSS 表达式(如 style="background:url(javascript:alert())")。真实场景中,用户输入往往要嵌入 HTML 属性、JS 字符串或 JSON,这时光去标签远远不够。
- 如果输出到 HTML 文本内容(比如
<p>{{ $text }}</p> <p><span>立即学习</span>“<a href="https://pan.quark.cn/s/7fc7563c4182" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">PHP免费学习笔记(深入)</a>”;</p><div class="aritcle_card flexRow"> <div class="artcardd flexRow"> <a class="aritcle_card_img" href="/ai/2410" title="遨虾"><img src="https://img.php.cn/upload/ai_manual/001/246/273/176421356013932.png" alt="遨虾" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a href="/ai/2410" title="遨虾">遨虾</a> <p>1688推出的跨境电商AI智能体</p> </div> <a href="/ai/2410" title="遨虾" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div>):先strip_tags(),再htmlspecialchars($text, ENT_QUOTES, 'UTF-8') - 如果输出到 HTML 属性值(比如
<div data-desc="'.$text.'">):必须用 <code>htmlspecialchars(),且ENT_QUOTES不可省 —— 单引号也要转 - 如果最终要
json_encode()后塞进 JS 变量:直接json_encode($text, JSON_UNESCAPED_UNICODE),别自己拼字符串 - 别手写正则匹配
]+>—— 无法处理注释、CDATA、嵌套引号,还容易被绕过 - 创建文档:
$dom = new DOMDocument(); $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); - 删 script/style:
$scripts = $dom->getElementsByTagName('script'); while ($scripts->length) { $scripts->item(0)->parentNode->removeChild($scripts->item(0)); } - 遍历所有元素,清空危险属性:
foreach ($dom->getElementsByTagName('*') as $el) { foreach (['onclick','onload','href','src'] as $attr) { if ($el->hasAttribute($attr)) { $el->removeAttribute($attr); } } } - 最后用
$dom->saveHTML()输出 —— 注意它会自动补,可用$dom->saveHTML($dom->documentElement)取 body 内容 - 小项目、低流量:用
strip_tags()+htmlspecialchars()组合足够 - 中大型 CMS 或用户可发带图文章:值得引入 HTMLPurifier,但必须跑通配置测试,尤其检查
<img alt="php怎么过滤html标签 php字符串去除html代码【重点】" >的src是否允许相对路径、data URI - 别在循环里反复 new HTMLPurifier —— 实例可复用,否则性能暴跌
复杂 HTML 需要保留结构?用 DOMDocument 手动清理
当你要保留 <p></p><ul></ul> 等语义标签,但删掉 <script></script><style></style> 和所有 onerror、href="javascript:" 这类危险属性时,strip_tags() 就不够用了。
用 DOMDocument 更可控,但要注意加载失败会报 Warning(比如遇到 malformed HTML),得提前 libxml_use_internal_errors(true) 抑制。
为什么不用第三方库(比如 HTMLPurifier)?
HTMLPurifier 功能最全,支持白名单、CSS 过滤、URI 校验,但体积大、初始化慢、配置复杂。如果你的项目只是做评论、简介这类简单富文本清洗,它属于「杀鸡用牛刀」。
容易踩的坑是:把它当成黑盒调用,没配 $config->set('HTML.Allowed', 'p,b,i,a[href]'); 就直接 purify,结果默认策略极保守,连 <br> 都被删了。
htmlspecialchars() 无效,必须走 json_encode()。










