如何防止PHP DOMDocument解析HTML时移除@click等自定义属性
问题原因
PHP的DOMDocument底层依赖libxml库,以HTML模式加载内容时,会默认过滤不符合HTML属性命名规范的属性,@开头的Vue/Alpine等框架的指令属性不属于标准HTML属性,因此会被自动移除。
方案1:属性名预处理转义+输出还原(推荐,兼容性最强)
思路是加载HTML前,把所有@开头的属性替换为符合HTML规范的自定义data-at-前缀属性,等DOM操作完成输出时,再替换回@前缀即可。
<?php $content = <<<'EOT' <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head></head> <body> <a role="tab" @click="activeType=listingType"></a> <input type="text" @autocomplete:change="handleAutocomplete"> </body> </html> EOT; // 预处理:把@开头的属性替换为data-at-前缀 $content = preg_replace('/\s@([a-zA-Z0-9:._-]+)=/', ' data-at-$1=', $content); $doc = new DOMDocument('1.0', 'utf-8'); $doc->recover = true; $doc->strictErrorChecking = false; libxml_use_internal_errors(true); $doc->loadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); // 此处可正常执行DOM操作逻辑... // 输出前把data-at-前缀还原为@ $output = $doc->saveHTML(); $output = preg_replace('/\sdata-at-([a-zA-Z0-9:._-]+)=/', ' @$1=', $output); echo $output; ?>
该方案优势:对HTML语法容错性和原生loadHTML一致,不需要修改原HTML结构,适配所有前端框架的@前缀指令。
方案2:以XML格式加载内容
XML解析模式不会强制校验HTML属性命名规则,只要标签语法符合XML规范(必须闭合、属性值加引号等),就可以保留所有自定义属性:
<?php $content = <<<'EOT' <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head></head> <body> <a role="tab" @click="activeType=listingType"></a> <input type="text" @autocomplete:change="handleAutocomplete" /> <!-- 注意XML模式下单标签必须加闭合斜线,比如input、img等都要写为/>格式 --> </body> </html> EOT; $doc = new DOMDocument('1.0', 'utf-8'); $doc->recover = true; $doc->strictErrorChecking = false; libxml_use_internal_errors(true); // 改用loadXML方法加载 $doc->loadXML($content); echo $doc->saveHTML(); ?>
注意点:该方案要求HTML必须严格符合XML语法,否则会出现解析错误,适合本身就是XHTML格式、语法规范的内容。
内容的提问来源于stack exchange,提问作者Gijo Varghese
相关产品推荐
相关产品推荐

