在PHP中如何正确剥离HTML标签?strip_tags等工具异常如何解决?
PHP字符串剥离HTML标签实操方案
针对你遇到的原生函数误判不完整标签、处理逻辑不符合预期的问题,可选择以下三种不同场景的解决方案:
方案1:基于DOMDocument的精准处理(推荐)
该方案依赖PHP内置的DOM解析能力,只会识别符合W3C规范的合法HTML标签,不会把<test这类不完整/非标准标签开头的内容判定为需要移除的标签,完全匹配你期望的处理规则,支持自定义允许保留的标签。
function strip_legal_html_tags(string $input, array $allowed_tags = []): string { if (trim($input) === '') { return $input; } // 预处理避免中文乱码 $input = mb_convert_encoding($input, 'HTML-ENTITIES', 'UTF-8'); $dom = new DOMDocument(); // 抑制非标准HTML的解析警告 libxml_use_internal_errors(true); $dom->loadHTML('<div>' . $input . '</div>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); libxml_clear_errors(); // 生成XPath查询规则,过滤需要保留的标签 $exclude_rules = []; foreach ($allowed_tags as $tag) { $exclude_rules[] = 'not(name()="' . strtolower($tag) . '")'; } $xpath = new DOMXPath($dom); foreach ($xpath->query('//*[' . implode(' and ', $exclude_rules) . ']') as $node) { // 保留标签内的文本内容,仅移除标签本身 $node->parentNode->replaceChild( $dom->createTextNode($node->textContent), $node ); } // 去掉外层包裹的div容器,还原原始内容 $result = preg_replace('/^<div>|<\/div>$/', '', trim($dom->saveHTML($dom->documentElement))); // 若需要移除单独存在的<符号,可放开下方注释 // $result = str_replace('<', '', $result); return html_entity_decode($result, ENT_QUOTES | ENT_HTML5, 'UTF-8'); }
调用示例:
// 测试输入 $test_str = '示例内容<test <p>这是合法段落标签</p> <h1>标题</h1>'; // 调用函数,允许保留p标签 echo strip_legal_html_tags($test_str, ['p']); // 输出结果:示例内容<test <p>这是合法段落标签</p> 标题
方案2:修改voku/anti-xss配置实现标签移除
你正在使用的voku/anti-xss库支持通过配置切换处理逻辑,不需要编码标签的话,开启remove_html_tags参数即可直接移除识别到的合法HTML标签,无需自己实现解析逻辑:
$antiXss = new \voku\helper\AntiXSS(); // 开启直接移除HTML标签的模式,而非默认编码 $antiXss->remove_html_tags = true; // 可选:添加需要保留的合法标签 // $antiXss->addAllowedHtmlTag('p'); // $antiXss->addAllowedHtmlTag('a'); $result = $antiXss->xss_clean($input);
方案3:轻量优化版strip_tags(性能优先)
如果对性能要求较高,不需要100%的标签识别准确率,可以在调用原生strip_tags前先预处理非合法标签开头的<符号,大幅降低误判概率:
function optimized_strip_tags(string $input, array $allowed_tags = []): string { // 合法HTML标签只能以字母、/、!开头,其余<开头内容先转义避免被strip_tags误删 $input = preg_replace_callback('/<([^a-z\/!])/i', function ($matches) { return '<' . $matches[1]; }, $input); // 生成允许的标签字符串 $allowed_tag_str = ''; foreach ($allowed_tags as $tag) { $allowed_tag_str .= "<$tag>"; } return html_entity_decode(strip_tags($input, $allowed_tag_str), ENT_QUOTES, 'UTF-8'); }
内容的提问来源于stack exchange,提问作者Andrei Dascalu
相关产品推荐
相关产品推荐

