使用simplehtmldom清理输入时childNodes触发foreach警告的问题
问题根源
simplehtmldom的childNodes属性实现和标准DOM不一样,有时候哪怕hasChildNodes()返回true,childNodes也可能返回布尔值而非可遍历的集合——比如元素里只有文本节点时,它的内部解析逻辑就会导致这种情况,这就是你报错的原因。
修复代码
直接在遍历childNodes前,先检查它是不是数组或对象,同时还要跳过文本节点(因为文本节点没有getAllAttributes()方法,硬调用会出新错)。修改后的代码如下:
$dom = str_get_html($ticket_text); foreach ($dom->find('*') as $elem) { // 移除当前元素的所有属性 foreach ($elem->getAllAttributes() as $attr => $val) { $elem->removeAttribute($attr); } // 先判断childNodes是否能遍历,再处理 if (is_array($elem->childNodes) || is_object($elem->childNodes)) { foreach ($elem->childNodes as $childNode) { // 只处理有属性方法的元素节点 if (method_exists($childNode, 'getAllAttributes')) { foreach ($childNode->getAllAttributes() as $attr => $val) { $childNode->removeAttribute($attr); } } } } }
可选优化:精准移除事件属性
如果你只是想删掉onclick、onkeydown这类事件属性,不是所有属性,可以改成下面的代码,更高效:
$dom = str_get_html($ticket_text); // 定义要移除的事件属性前缀 $eventAttrs = ['on']; foreach ($dom->find('*') as $elem) { foreach ($elem->getAllAttributes() as $attr => $val) { // 匹配以on开头的属性 foreach ($eventAttrs as $prefix) { if (str_starts_with($attr, $prefix)) { $elem->removeAttribute($attr); break; } } } if (is_array($elem->childNodes) || is_object($elem->childNodes)) { foreach ($elem->childNodes as $childNode) { if (method_exists($childNode, 'getAllAttributes')) { foreach ($childNode->getAllAttributes() as $attr => $val) { foreach ($eventAttrs as $prefix) { if (str_starts_with($attr, $prefix)) { $childNode->removeAttribute($attr); break; } } } } } } }
内容的提问来源于stack exchange,提问作者user22805937
相关产品推荐
相关产品推荐

