【发布时间】:2014-12-28 04:32:39
【问题描述】:
我用 PHP 编写了这个小测试代码,试图掌握 DOMDocument::getElementById 的工作原理。我这样写是为了可以使用方法链。
<?php
class SMHtmlElement extends DOMElement {
public function __construct($name, $value = NULL, $namespaceURI = NULL) {
parent::__construct($name, $value, $namespaceURI);
}
public function attr($attribute, $value) {
if (!empty($attribute)) {
$this->setAttribute($attribute, $value);
}
return $this;
}
public function id($value) {
$this->attr('id', $value);
// this doesn't helped.
@$this->ownerDocument->validate();
$this->setIdAttribute('id',TRUE);
return $this;
}
}
class SMHtmlDocument extends DOMDocument {
private $body;
public function __construct() {
parent::__construct("1.0", "UTF-8");
$this->validateOnParse = true;
$this->loadHTML('<!DOCTYPE html><html><head></head><body></body></html>');
$this->body = $this->getElementsByTagName('body')->item(0);
}
public final function bodyAdd($element, $beforeElement = NULL) {
$el = new SMHtmlElement($element);
if ($beforeElement)
$beforeElement->insertBefore($el);
else
$this->body->appendChild($el);
return $el;
}
}
// this search should work it didn't
$dom = new SMHtmlDocument();
$p1 = $dom->bodyAdd('p')->id('foo');
$p = $dom->getElementById('foo');
echo $dom->saveHTML();
var_dump($p);
// when set the ID outside the method, it works.
$p2 = $dom->getElementsByTagName('p')->item(0);
$p2->setIdAttribute('id',true);
$p = $dom->getElementById('foo');
var_dump($p);
// let's see if both paragraph elements are the same
var_dump($p1->isSameNode($p2));
?>
执行之后,我得到了这样的输出:
$> php teste.php
<!DOCTYPE html>
<html><head></head><body><p id="foo"></p></body></html>
NULL // first var_dump()
object(DOMElement)#4 (0) { // second var_dump()
}
bool(true)
如您所见,我已在方法 id() 中将属性 id 标记为 ID,但它不起作用。但是当我在对象外部调用 setIdAttribute() 方法时,它确实起作用了。
这里的一些帖子建议使用 DTD,但是当我尝试生成 HTML5 时,据我所知,HTML5 不是基于 DTD。我也知道我可以使用 XPath 来找到我想要的 id,但我真的想了解为什么我的代码不能正常工作。
我在安装了 PHP 5.3 的 Ubuntu 12.04 服务器上运行它。
谁能解释一下发生了什么?
谢谢!
【问题讨论】: