Couper une chaîne en concervant les balises HTML

16 Novembre 2013 à 00:00 Programmation

Je ne publierai plus rien sur ce blog. Un nouveau blog existe maintenant. Il se nomme Hardly Smart.

Vous pourrez y retrouver des astuces plus larges sur l'informatique ainsi que mes anciens billets de blog.

Je vous souhaite une bonne lecture sur Hardly Smart.


Pour mon travail je dois développer un système de news et il faut que sur la page d'acceuil, on n'affiche qu'une petite partie de la news. J'avais bien sûr penser à utiliser la fonction php substr() :

Alors je vous rassure, ce n'est pas moi qui ait adapté cette fonction. Non je l'ai trouvé sur ce site : http://www.ycerdan.fr/php/tronquer-un-texte-en-conservant-les-tags-html-en-php/

Je vous laisse vous rendre sur son site pour voir comment l'utiliser et regarder les exemples qu'il donne afin que le mérite lui revienne. Je ne fais que partager ma découverte

$string = "

Mon texte récupéré depuis ma base de données SQL

"; echo substr ($string , 0, 25);

Ce qui donne :

Mon texte récupéré dep

Sauf que le problème comme vous pouvez le voir c'est que si jamais vous utiliser comme moi un système tel que CKEditor ou TinyMCE, il va forcément avoir des balises qui vont se glisser dans votre texte récupéré depuis votre base de données et du coup votre site va être totalement déformé à cause des balises coupés.

En cherchant sur Internet et en postant sur un forum on m'a conseillé cette fonction que je vous copie juste en dessus. Elle est à la base du framework PHP CakePHP et un peu modifiée. Vous devez néanmoins avoir activé la fonction mbstring :

Source

/**
 * Truncates text.
 *
 * Cuts a string to the length of $length and replaces the last characters
 * with the ending if the text is longer than length.
 *
 * @param string  $text String to truncate.
 * @param integer $length Length of returned string, including ellipsis.
 * @param mixed $ending If string, will be used as Ending and appended to the trimmed string. Can also be an associative array that can contain the last three params of this method.
 * @param boolean $exact If false, $text will not be cut mid-word
 * @param boolean $considerHtml If true, HTML tags would be handled correctly
 * @return string Trimmed string.
 */
  
function truncate($text, $length = 100, $ending = '...', $exact = true, $considerHtml = false) {
    if (is_array($ending)) {
        extract($ending);
    }
    if ($considerHtml) {
        if (mb_strlen(preg_replace('//', '', $text)) ]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER);
        foreach ($tags as $tag) {
            if (!preg_match('/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/s', $tag[2])) {
                if (preg_match('/]*>/s', $tag[0])) {
                    array_unshift($openTags, $tag[2]);
                } else if (preg_match('/<\/([\w]+)[^>]*>/s', $tag[0], $closeTag)) {
                    $pos = array_search($closeTag[1], $openTags);
                    if ($pos !== false) {
                        array_splice($openTags, $pos, 1);
                    }
                }
            }
            $truncate .= $tag[1];
 
            $contentLength = mb_strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $tag[3]));
            if ($contentLength + $totalLength > $length) {
                $left = $length - $totalLength;
                $entitiesLength = 0;
                if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', $tag[3], $entities, PREG_OFFSET_CAPTURE)) {
                    foreach ($entities[0] as $entity) {
                        if ($entity[1] + 1 - $entitiesLength = $length) {
                break;
            }
        }
 
    } else {
        if (mb_strlen($text) /', $bits, $droppedTags, PREG_SET_ORDER);
                if (!empty($droppedTags)) {
                    foreach ($droppedTags as $closingTag) {
                        if (!in_array($closingTag[1], $openTags)) {
                            array_unshift($openTags, $closingTag[1]);
                        }
                    }
                }
            }
            $truncate = mb_substr($truncate, 0, $spacepos);
        }
    }
 
    $truncate .= $ending;
 
    if ($considerHtml) {
        foreach ($openTags as $tag) {
            $truncate .= '';
        }
    }
 
    return $truncate;
}

Articles liés

Les commentaires ont été désactivés.

0 commentaire