Я столкнулся с проблемами, когда я пытался ограничить содержание description
, я пробовал вот так:
<?php $intDescLt = 400; $content = $arrContentList[$arr->nid]['description']; $excerpt = substr($content, 0, $intDescLt); ?> <div class="three16 DetailsDiv"> <?php echo $excerpt; ?> <div>
В поле описания, если я просто помещаю контент без html-тегов, он работает нормально, но если я поместил контент в теги html и, если предел достигнет конца до закрытия тега, он применил этот стиль табуляции ко всему содержимому после этого.
Поэтому мне нужно знать, как я могу решить эту проблему.
Ex. Проблема:
$string = "<p><b>Lorem Ipsum</b> is simply dummy text of the printing and typesetting industry.</p>"; echo substr($string, 0, 15);
Выход Html в консоли: <p><b>Lorem Ipsu
И теперь он применил <b>
к остальной части содержимого на странице.
Ожидаемый вывод в консоли: <p><b>Lorem Ipsu</b>
Хорошо, учитывая приведенный вами пример:
$string = "<p><b>Lorem Ipsum</b> is simply dummy text of the printing and typesetting industry.</p>"; $substring = substr((addslashes($string)),0,15);
В случае возможного решения следует использовать класс DOMDocument, если вы хотите закрыть все закрытые теги:
$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>
Вы не можете просто использовать двоичные строковые функции PHP в строке HTML, а затем ожидать, что все будет работать.
$string = "<p><b>Lorem Ipsum</b> is simply dummy text of the printing and typesetting industry.</p>";
Прежде всего вам нужно сформулировать, какую выдержку вы хотели бы создать в контексте HTML. Возьмем пример, который касается фактической длины текста в символах. Это не учитывает размер тегов HTML. Также теги должны быть закрыты.
Вы начинаете с создания DOMDocument, чтобы вы могли работать с фрагментом HTML, который у вас есть. Загружаемая $string
будет дочерними узлами <body>
, поэтому код получает это для справки:
$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);
Далее необходимо работать со всеми узлами внутри него в порядке документа. Итерация этих узлов может быть легко достигнута с помощью запроса 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); } }
В конце вам нужно включить внутренний HTML тега body в строку, чтобы получить результат:
$buffer = ''; foreach ($body->childNodes as $node) { $buffer .= $doc->saveHTML($node); } echo $buffer;
Это даст вам следующий результат:
<p><b>Lorem Ipsum</b> is </p>
Поскольку элементы узла были изменены, но только текстовые узлы, элементы все еще остаются нетронутыми. Просто текст был сокращен. Объектная модель документа позволяет вам выполнять обход, строковые операции, а также удаление узлов по мере необходимости.
Как вы можете себе представить, более упрощенная строковая функция, такая как substr()
, не способна обрабатывать HTML.
На самом деле может быть больше: HTML в строке может быть недействительным (проверьте расширение Tidy), вы можете отказаться от атрибутов и тегов HTML (изображений, скриптов, iframe), и вы также можете захотеть поместить размер теги во внимание. DOM позволит вам это сделать.
Пример в полном объеме ( онлайн-демонстрация ):
<?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;