PHP原生DOM库DOMElement::setIdAttribute重复调用异常问题咨询
结论:该行为属于PHP DOM扩展的实现Bug,并非设计特性
你定位到的源码逻辑确实存在疏漏,问题核心出在php_set_attribute_id函数的分支判断逻辑:
- 第二次调用
$element->setIdAttribute("id", true)时,属性的atype已经是XML_ATTRIBUTE_ID,不满足is_id == 1 && attrp->atype != XML_ATTRIBUTE_ID的正向判断条件,会直接进入else分支,将已有的ID标记移除、atype重置为0,最终导致isId()返回false。 - 该逻辑完全不符合W3C DOM规范对
setIdAttribute方法的定义:当传入第二个参数为true时,无论该属性之前是否为ID类型,执行后都应将该属性声明为ID类型。你在Java中测试得到的结果才是符合规范的预期行为。
临时兼容方案
在PHP官方修复该问题前,可以通过两种方式规避:
- 调用前先判断属性是否已经是ID类型,避免重复调用:
$idAttr = $element->getAttributeNode('id'); if (!$idAttr->isId()) { $element->setIdAttribute('id', true); }
- 每次设置前先显式移除ID标记再重新添加,保证结果符合预期:
$element->setIdAttribute('id', false); $element->setIdAttribute('id', true);
内容的提问来源于stack exchange,提问作者Jacobian
相关产品推荐
相关产品推荐

