PHP中的HTML DOM操作

3

我想知道如何使用PHP操作DOM树?

我看到一些答案使用加载HTML文件的XML DOM。但是如果我不需要加载呢?如果我要操作的文档中有XML DOM脚本怎么办?

下面有一个示例,它会打印出所有的文件夹。请填写你的答案中的空白部分。我想创建带有文件夹名称作为文本节点的div元素。答案需要包含一些XML DOM脚本,因为我将在我的网站上创建多个元素而不仅仅是一个div元素。例如使用echo并不实用,因为你可能会将一个元素插入到错误的元素中。

$sql = "
    SELECT name
    FROM folders
    WHERE profileId = '$profileId'
";
$result = mysql_query($sql) or die('Error6: '.mysql_error());
while($row = mysql_fetch_array($result)) {

}

请澄清一下,您的问题是在一个地方构建了一个类似于<div id=my-id ></div>的字符串,然后在代码的其他地方想要将一个节点插入到该div中? - Ruan Mendes
6个回答

6
您不需要使用PHP来操作已经生成的文档的DOM。直接让PHP生成一些HTML代码就更容易了。DOM是用来解析/更改在其他地方生成的HTML代码的。换句话说,您的脚本只需如下所示:
while($row = mysql_fetch_array($result)) {
    echo "<div>{$row['name']}</div>";
}

DOM示例,以展示其繁琐性

好的,这里是生成带有一些内部等等的文本段落的PHP方法:

echo "<div> This is my div, <span>There are many like it, <b>but this one</b> is</span> mine</div>";
等效的 DOM 调用(未经测试,仅供演示):
$dom = new DOM;

$bold = new DOMElement('b');
$bold->appendChild(new DOMText('but this one'));

$span = new DOMElement('span');
$span->appendChild(new DOMText('There are many like it,'));
$span->appendChild($bold);
$span->appendChild(new DOMText(' is');

$div = new DOMElement('div');
$div->appendChild(new DOMText(' This is my div,'));
$div->appendChild($span);
$div->appendChild(' mine');

echo $div->saveXML();
那么……你还认为使用DOM比使用echo更容易吗?

每次都使用echo太麻烦了。如果我有多个div元素怎么办? - einstein
@Woho:在PHP中使用echo输出一些HTML比使用DOM调用逐个构建文档节点要容易得多。如果您有更多内容要放入div中,那么只需回显HTML片段即可。否则,您将被困在一长串“创建节点”,“填充节点”,“插入节点”序列中。 - Marc B
使用echo仅适用于简单的HTML,因为构建更复杂的结构,特别是以非顺序方式构建,是繁琐且容易出错的。此外,在simplexml或dom中创建元素会自动处理编码实体。每当我使用dom时,我都会构建几个帮助函数来执行常见任务,例如在具有多个属性的另一个元素上创建元素。Simplexml更易于用于大多数dom构建工作,只有在插入使用simplexml构建的孤立元素时才会使用dom。 - Patanjali
非顺序 DOM 构建的一个示例是在使用文件来保存 HTML 的同时,通过多个 Web 往返语义化地构建它。另一种选择是在构建结构并使用 XSL 生成 HTML 时将内容存储在 XML 文件中。 - Patanjali

3

如果需要使用PHP进行DOM操作,可以尝试使用phpQuery。如果您熟悉jQuery,那么相似的语法使其成为一个好的库。


可悲的是,phpQuery现在已经停止维护了。它曾是我的首选解决此类问题的工具。phpgt/dom看起来很有前途。请参阅上面@Greg的答案。 - datashaman

1
我发现使用PHP内置的DOM实现(libxml)非常笨重,因为它仅支持DOM 2。我更喜欢使用phpgt/dom(https://github.com/phpgt/dom),可以通过composer获得

用法示例:

$document = new \phpgt\dom\HTMLDocument(
    "<!doctype html><h1>My list of amazing things</h1> <ul class='my-list'></ul>"
);

$result = $database->query("SELECT thing FROM Amazing");
$ul_output = $document->querySelector("ul.my-list");

foreach($result as $row) {
    $li = $document->createElement("li");
    $li->textContent = $row["thing"];
    $ul_output->appendChild($li);
}

echo $document->saveHTML();

项目的Github Wiki上提供了完整的文档:https://github.com/phpgt/dom/wiki


0

如果您认为PHP在回显HTML时会创建DOM,那是不会发生的。但是,您可以使用Marc B样本生成DOM节点(您可以将其附加到其中)。在操作该节点后,您可以使用http://www.php.net/manual/en/domdocument.savehtml.php发出节点的HTML。


0

我希望我理解得正确。

$result = mysql_query($sql) or die('Error6: '.mysql_error());
while($row = mysql_fetch_array($result)){
   ?><div><?php echo $result[0]; ?></div><?php
}
如果这不是您要寻找的,请详细说明您想要实现什么。

你需要在PHP中使用XML DOM。因为我将创建许多HTML元素。 - einstein

0
从技术上讲,这是预 DOM,因为您在将页面输出到客户端之前在 HTML 中构建页面,在此时它成为客户端上下文中的文档对象模型。因此,您的 DOM 操作实际上只是在服务器端使用 PHP 生成 HTML。
<html>
<head>
</head>
<body>

<?php
$sql = "
SELECT name
FROM folders
WHERE profileId = '".mysql_escape_string($profileId)."'
";
$result = mysql_query($sql) or die('Error6: '.mysql_error());
while($row = mysql_fetch_array($result)){
  echo "<div>".htmlentities($row['name'])."</div>";
}
?>
</body></html>

我还在您的SQL语句中添加了mysql_escape_string以帮助防止SQL注入攻击,同时在echo输出上使用htmlentities以帮助防止脚本注入到页面中。


我认为为了完整回答Woho87的问题,他们需要提供一个期望发送给客户端的输出示例。 - dunos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,