Skip to content Skip to sidebar Skip to footer

Limited Content Break The Html Layout In Php

I am facing an issues when I tried to limit the content of description , I have tried like this : nid]['descriptio

Solution 1:

You can't just use PHP's binary string functions on a HTML string and then expect things to work.

$string = "<p><b>Lorem Ipsum</b> is simply dummy text of the printing and typesetting industry.</p>";

First of all you need to formulate what kind of excerpt you'd like to create in the HTML context. Let's take an example that is concerned about the actual text-length in characters. That is not counting the size of the HTML tags. Also tags should be kept closing.

You start by creating a DOMDocument so that you can operate on the HTML fragment you have. The $string loaded will be the child-nodes of the <body> tag, so the code gets it for reference as well:

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

Next is needed to operate on all the nodes within it in document order. Iterating these nodes can be easily achieved with the help of an xpath query:

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

Then the logic on how to create the excerpt needs to be implemented. That is all text-nodes are taken over until their length exceeds the number of characters left. If so, they are split or if no characters are left removed from their parent:

$length = 0;
foreach ($nodesas$node) {
    if (!$nodeinstanceof 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);
    }
}

At the end you need to turn in inner HTML of the body tag into a string to obtain the result:

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

echo$buffer;

This will give you the following result:

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

As node elements have been altered but only text-nodes, the elements are still intact. Just the text has been shortened. The Document Object Model allows you to do the traversal, the string operations as well as node-removal as needed.

As you can imagine, a more simplistic string function like substr() is not similarly capable of handling the HTML.

In reality there might be more to do: The HTML in the string might be invalid (check the Tidy extension), you might want to drop HTML attributes and tags (images, scripts, iframes) and you might also want to put the size of the tags into account. The DOM will allow you to do so.

The example in full (online demo):

<?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) {
    thrownewInvalidArgumentException('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 ($nodesas$node) {
    if (!$nodeinstanceof 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;

Solution 2:

Ok, given the example you provided:

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

On possible solution is to use the DOMDocument class if you want to close all unclosed tags:

$doc = new DOMDocument();
$doc->loadHTML($substring);
$yourText = $doc->saveHTML($doc->getElementsByTagName('*')->item(2));
//item(0) = html//item(1) = bodyecho htmlspecialchars($yourText);
//<p><b>Lorem Ips</b></p>

Post a Comment for "Limited Content Break The Html Layout In Php"