有限的内容打破了php中的HTML布局

有限的内容打破了php中的HTML布局,php,html,string,Php,Html,String,当我试图限制说明的内容时,我遇到了一个问题,我试过这样做: <?php $intDescLt = 400; $content = $arrContentList[$arr->nid]['description']; $excerpt = substr($content, 0, $intDescLt); ?> <div class="three16 DetailsDiv"> <?php echo $excerpt; ?> <div&

当我试图限制
说明
的内容时,我遇到了一个问题,我试过这样做:

<?php 
$intDescLt = 400;
$content   = $arrContentList[$arr->nid]['description'];
$excerpt   = substr($content, 0, $intDescLt);
?>
<div class="three16 DetailsDiv">
    <?php echo $excerpt; ?>
<div>

在description字段中,如果我只是将内容放在没有html标记的位置,效果会很好,但是如果我将内容放在带有html标记的位置,并且如果将limit reach放在closing标记之前的末尾,它会将该选项卡样式应用于之后的所有内容

所以我需要知道如何解决这个问题

Ex. 问题:

$string = "<p><b>Lorem Ipsum</b> is simply dummy text of the printing and typesetting industry.</p>";
echo substr($string, 0, 15);
$string=“Lorem Ipsum只是印刷和排版行业的虚拟文本。

”; echo substr($string,0,15);
控制台中的Html输出:
Lorem Ipsu
现在它将
标记应用于页面中的其余内容


控制台中的预期输出:
Lorem Ipsu

根据您提供的示例,确定:

$string = "<p><b>Lorem Ipsum</b> is simply dummy text of the printing and typesetting industry.</p>";
$substring = substr((addslashes($string)),0,15);
$string=“Lorem Ipsum只是印刷和排版行业的虚拟文本。

”; $substring=substr((addslashes($string)),0,15);
如果要关闭所有未关闭的标记,可能的解决方案是使用:

$doc = new DOMDocument();
$doc->loadHTML($substring);
$yourText = $doc->saveHTML($doc->getElementsByTagName('*')->item(2));
//item(0) = html
//item(1) = body
echo htmlspecialchars($yourText);
//<p><b>Lorem Ips</b></p>
$doc=newDOMDocument();
$doc->loadHTML($substring);
$yourText=$doc->saveHTML($doc->getElementsByTagName('*')->item(2));
//项目(0)=html
//第(1)项=正文
回显htmlspecialchars($yourText);
// 洛雷姆Ips


您不能只在HTML字符串上使用PHP的二进制字符串函数,然后期望一切正常

$string = "<p><b>Lorem Ipsum</b> is simply dummy text of the printing and typesetting industry.</p>";
接下来需要按文档顺序对其中的所有节点进行操作。借助xpath查询,可以轻松实现对这些节点的迭代:

$xp    = new DOMXPath($doc);
$nodes = $xp->query('./descendant::node()', $body);
然后需要实现关于如何创建摘录的逻辑。也就是说,将接管所有文本节点,直到其长度超过剩余的字符数。如果是,则它们将被删除,或者如果没有从其父级中删除任何字符:

$length = 0;
foreach ($nodes as $node) {
    if (!$node instanceof DOMText) {
        continue;
    }
    $left = max(0, 15 - $length);
    if ($left) {
        if ($node->length > $left) {
            $node->splitText($left);
            $node->nextSibling->parentNode->removeChild($node->nextSibling);
        }
        $length += $node->length;
    } else {
        $node->parentNode->removeChild($node);
    }
}
最后,您需要将body标记的内部HTML转换为字符串以获得结果:

$buffer = '';
foreach ($body->childNodes as $node) {
    $buffer .= $doc->saveHTML($node);
}

echo $buffer;
这将为您提供以下结果:

<p><b>Lorem Ipsum</b> is </p>

那么,通过一个例子,您当前和预期的输出是什么?另外,是否要限制包含或不包含html标记的文本?如果你想用html标签来限制它,它应该关闭html标签吗?如果它太长,还是只需要较少的文本,这样它就可以与html标签匹配?是的,我想用html标签来限制内容,是的,它应该关闭html标签。请用一些示例代码向你的案例展示你想要的。我已经更新了问题,请检查。但是为什么不关闭p标签,只关闭b标签呢?看不出这背后的模式
<p><b>Lorem Ipsum</b> is </p>
<?php
/**
 * Limited content break the HTML layout in php
 *
 * @link http://stackoverflow.com/a/29323396/367456
 * @author hakre <http://hakre.wordpress.com>
 */

$string = "<p><b>Lorem Ipsum</b> is simply dummy text of the printing and typesetting industry.</p>";
echo substr($string, 0, 15), "\n";

$doc    = new DOMDocument();
$result = $doc->loadHTML($string);
if (!$result) {
    throw new InvalidArgumentException('String could not be parsed as HTML fragment');
}
$body = $doc->getElementsByTagName('body')->item(0);

$xp    = new DOMXPath($doc);
$nodes = $xp->query('./descendant::node()', $body);

$length = 0;
foreach ($nodes as $node) {
    if (!$node instanceof DOMText) {
        continue;
    }
    $left = max(0, 15 - $length);
    if ($left) {
        if ($node->length > $left) {
            $node->splitText($left);
            $node->nextSibling->parentNode->removeChild($node->nextSibling);
        }
        $length += $node->length;
    } else {
        $node->parentNode->removeChild($node);
    }
}

$buffer = '';
foreach ($body->childNodes as $node) {
    $buffer .= $doc->saveHTML($node);
}

echo $buffer;