修复未封闭的 HTML 标签

问题描述 投票:0回答:4

我正在设计一些博客布局,我需要创建每篇文章的摘要(比如最新的 15 篇文章)以显示在主页上。现在我使用的内容已经由纺织库格式化为 html 标签。现在,如果我使用 substr 获取帖子的第 500 个字符,我面临的主要问题是如何关闭未关闭的标签。

例如

<div>.......................</div>
<div>...........
     <p>............</p>
     <p>...........| 500 chars
     </p>
<div>  

我得到的是两个未闭合的标签

,p不会造成太多麻烦,但div只会弄乱整个页面布局。那么有什么建议如何跟踪开始标签并手动关闭它们或其他什么吗?

可以使用的方法有很多:

  1. 使用正确的 HTML 解析器,例如 DOMDocument
  2. 使用 PHP Tidy 修复未关闭的标签
  3. 有些人会建议HTML Purifier

正如 ajreal 所说,DOMDocument 是一个解决方案。

示例:

$str = "
<html>
 <head>
  <title>test</title>
 </head>
 <body>
  <p>error</i>
 </body>
</html>
";

$doc = new DOMDocument();
@$doc->loadHTML($str);
echo $doc->saveHTML();

优点:原生包含在 PHP 中,与 PHP Tidy 相反。

可以使用 DOMDocument 来完成,但要注意字符串编码问题。此外,您还必须使用完整的 HTML 文档,然后提取所需的组件。这是一个例子:

function make_excerpt ($rawHtml, $length = 500) {
  // append an ellipsis and "More" link
  $content = substr($rawHtml, 0, $length)
    . '&hellip; <a href="/link-to-somewhere">More &gt;</a>';

  // Detect the string encoding
  $encoding = mb_detect_encoding($content);

  // pass it to the DOMDocument constructor
  $doc = new DOMDocument('', $encoding);

  // Must include the content-type/charset meta tag with $encoding
  // Bad HTML will trigger warnings, suppress those
  @$doc->loadHTML('<html><head>'
    . '<meta http-equiv="content-type" content="text/html; charset='
    . $encoding . '"></head><body>' . trim($content) . '</body></html>');

  // extract the components we want
  $nodes = $doc->getElementsByTagName('body')->item(0)->childNodes;
  $html = '';
  $len = $nodes->length;
  for ($i = 0; $i < $len; $i++) {
    $html .= $doc->saveHTML($nodes->item($i));
  }
  return $html;
}

$html = "<p>.......................</p>
  <p>...........
    <p>............</p>
    <p>...........| 500 chars";

// output fixed html
echo make_excerpt($html, 500);

输出:

<p>.......................</p>
  <p>...........
    </p>
<p>............</p>
    <p>...........| 500 chars… <a href="/link-to-somewhere">More &gt;</a></p>

如果您使用 WordPress,则应将

substr()
调用包装在对
wpautop
-
wpautop(substr(...))
的调用中。您可能还希望测试传递给函数的 $rawHtml 的长度,如果不够长,则跳过附加“更多”链接。

我找到了一个使用 DOMDocument 但不会向字符串添加额外标签的解决方案;只是修复格式错误的 HTML。 请参阅此处的答案:https://stackoverflow.com/a/79081559/492132

原始github(不是我的)在这里:https://gist.github.com/hubgit/1322324

php html dom
4个回答
18
投票

可以使用的方法有很多:

  1. 使用正确的 HTML 解析器,例如 DOMDocument
  2. 使用 PHP Tidy 修复未关闭的标签
  3. 有些人会建议HTML Purifier

18
投票

正如 ajreal 所说,DOMDocument 是一个解决方案。

示例:

$str = "
<html>
 <head>
  <title>test</title>
 </head>
 <body>
  <p>error</i>
 </body>
</html>
";

$doc = new DOMDocument();
@$doc->loadHTML($str);
echo $doc->saveHTML();

优点:原生包含在 PHP 中,与 PHP Tidy 相反。


3
投票

可以使用 DOMDocument 来完成,但要注意字符串编码问题。此外,您还必须使用完整的 HTML 文档,然后提取所需的组件。这是一个例子:

function make_excerpt ($rawHtml, $length = 500) {
  // append an ellipsis and "More" link
  $content = substr($rawHtml, 0, $length)
    . '&hellip; <a href="/link-to-somewhere">More &gt;</a>';

  // Detect the string encoding
  $encoding = mb_detect_encoding($content);

  // pass it to the DOMDocument constructor
  $doc = new DOMDocument('', $encoding);

  // Must include the content-type/charset meta tag with $encoding
  // Bad HTML will trigger warnings, suppress those
  @$doc->loadHTML('<html><head>'
    . '<meta http-equiv="content-type" content="text/html; charset='
    . $encoding . '"></head><body>' . trim($content) . '</body></html>');

  // extract the components we want
  $nodes = $doc->getElementsByTagName('body')->item(0)->childNodes;
  $html = '';
  $len = $nodes->length;
  for ($i = 0; $i < $len; $i++) {
    $html .= $doc->saveHTML($nodes->item($i));
  }
  return $html;
}

$html = "<p>.......................</p>
  <p>...........
    <p>............</p>
    <p>...........| 500 chars";

// output fixed html
echo make_excerpt($html, 500);

输出:

<p>.......................</p>
  <p>...........
    </p>
<p>............</p>
    <p>...........| 500 chars… <a href="/link-to-somewhere">More &gt;</a></p>

如果您使用 WordPress,则应将

substr()
调用包装在对
wpautop
-
wpautop(substr(...))
的调用中。您可能还希望测试传递给函数的 $rawHtml 的长度,如果不够长,则跳过附加“更多”链接。


0
投票

我找到了一个使用 DOMDocument 但不会向字符串添加额外标签的解决方案;只是修复格式错误的 HTML。 请参阅此处的答案:https://stackoverflow.com/a/79081559/492132

原始github(不是我的)在这里:https://gist.github.com/hubgit/1322324

© www.soinside.com 2019 - 2024. All rights reserved.