Shorten text without splitting words or breaking html tags

前端 未结 8 1353
粉色の甜心
粉色の甜心 2020-12-28 17:06

I am trying to cut off text after 236 chars without cutting words in half and preserving html tags. This is what I am using right now:

$shortdesc = $_helper-         


        
8条回答
  •  春和景丽
    2020-12-28 17:35

    This will work with Unicode (from @nice ass answer):

    class Html
    {
        protected
            $reachedLimit = false,
            $totalLen = 0,
            $maxLen = 25,
            $toRemove = [];
    
        public static function trim($html, $maxLen = 25)
        {
    
            $dom = new \DOMDocument();
            $dom->loadHTML('' . $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
    
            $instance = new static();
            $toRemove = $instance->walk($dom, $maxLen);
    
            // remove any nodes that exceed limit
            foreach ($toRemove as $child) {
                $child->parentNode->removeChild($child);
            }
    
            return $dom->saveHTML();
        }
    
        protected function walk(\DOMNode $node, $maxLen)
        {
    
            if ($this->reachedLimit) {
                $this->toRemove[] = $node;
            } else {
                // only text nodes should have text,
                // so do the splitting here
                if ($node instanceof \DOMText) {
                    $this->totalLen += $nodeLen = mb_strlen($node->nodeValue);
    
                    // use mb_strlen / mb_substr for UTF-8 support
                    if ($this->totalLen > $maxLen) {
                        dump($node->nodeValue);
                        $node->nodeValue = mb_substr($node->nodeValue, 0, $nodeLen - ($this->totalLen - $maxLen)) . '...';
                        $this->reachedLimit = true;
                    }
                }
    
                // if node has children, walk its child elements
                if (isset($node->childNodes)) {
                    foreach ($node->childNodes as $child) {
                        $this->walk($child, $maxLen);
                    }
                }
            }
    
            return $this->toRemove;
        }
    }
    

提交回复
热议问题