Ces derniers temps il m’arrive souvent d’avoir besoin de travailler des chaînes de caractères pour des mises en pages précises, pour ne pas dire complexes.
Lors d’un projet j’ai eu à faire ressortir le début d’un extrait de page que je devais insérer dans un bloc, tout en conservant une deuxième partie de cet extrait placé à la suite.
Un exemple étant plus parlant, imaginez que le script ait pour but de placer le début de cet article que vous êtes en train de lire dans un cadre de taille réduite. De cet extrait je dois en plus en faire ressortir le début de la phrase. La chose ressemblerait à ça :
Ces derniers temps il m’arrive souvent d’avoir besoin de travailler des chaînes de caractères pour des mises en pages précises, pour ne pas dire complexes.
Lors d’un projet j’ai eu à faire ressortir le début d’un extrait de page […]
Pour corser l’exercice, il était possible que ce contenu récupéré ait en plus une structure déjà existante (élément p
, strong
, a
, blockquote
, etc.)
Pour l’exemple, on imaginera que la variable $contenu
contient un article complet.
Première méthode : mb_substr()
, substr()
et strrpos()
<?php
// création de la fonction curString à 4 paramètres
// $string = la chaîne tronquer
// $start = le caractère de départ
// $length = la longueur de la chaîne (en caractère)
// $endStr = paramètre optionnel qui termine l'extrait ([…] par défaut)
function cutString($string, $start, $length, $endStr = '[&hellip]'){
// si la taille de la chaine est inférieure ou égale à celle
// attendue on la retourne telle qu'elle
if( strlen( $string ) <= $length ) return $string;
// autrement on continue
// permet de couper la phrase aux caractères définis tout
// en prenant en compte la taille de votre $endStr et en
// re-précisant l'encodage du contenu récupéré
$str = mb_substr( $string, $start, $length - strlen( $endStr ) + 1, 'UTF-8');
// retourne la chaîne coupée avant la dernière espace rencontrée
// à laquelle s'ajoute notre $endStr
return substr( $str, 0, strrpos( $str,' ') ).$endStr;
}
$article = "Ici tout mon article avec plein de balises partout !";
// nettoyage des balises du contenu
$content = strip_tags( $article );
// on coupe notre contenu pour la première partie (en gras)
$part1 = cutString($content, 0, 100, '');
// on coupe le même contenu pour avoir la deuxième partie
// en partant du nombre de caractères de la première
$part2 = cutString($content, strlen($part1)-1, 315)
// on affiche notre code
echo '<p>';
echo '<strong>'.$part1.'</strong>';
echo $part2;
echo '</p>';
?>
Voilà ! Beaucoup de commentaires mais pas beaucoup de code.
Cette fonction a l’avantage d’être customisable et adaptable pour un CMS. L’idéal étant de l’avoir dans une page regroupant les fonctions communes de votre site web afin de la réutiliser facilement.
Il vous sera facile de simplifier le code présenté. Ici j’ai volontairement multiplié les lignes et les echo
pour rendre le code plus lisible.
Deuxième méthode : wordwrap()
(mise à jour du 09/05/2011)
L’idée m’a été introduite par Dew, mais au départ je ne voyais pas bien comment l’utiliser dans mon cas.
En effet, initialement cette fonction sert à manipuler cycliquement une chaîne de caractère en y introduisant un break, un élément servant de cassure.
Voilà ce que ça peut donner :
<?php
$contenu = "Lorem Elsass ipsum amet dui jetz gehts los leverwurscht non porta ac baeckeoffe ac bredele";
$text = wordwrap($contenu, 22, "
", true);
echo $text;
?>
Affichera :
Lorem Elsass ipsum
amet dui jetz gehts
los leverwurscht non
porta ac baeckeoffe ac
bredele
En voyant ça je me suis dit que ça pouvait effectivement être une bonne fonction, mais que dans mon cas je ne voyais pas trop l’utilité.
Mais en réfléchissant un peu, j’ai finalement détourné le fameux break pour faire ceci :
<?php
$contenu = "Lorem Elsass ipsum amet dui jetz gehts los leverwurscht non porta ac baeckeoffe ac bredele";
$text = wordwrap($contenu, 22, "***", true); // insertion de marqueurs ***
$tcut = explode("***", $text); // on créé un tableau à partir des marqueurs ***
$part1 = $tcut[0]; // la partie à mettre en exergue
$part2 = '';
for($i=1; $i<count($tcut); $i++) {
$part2 .= $tcut[$i].' ';
}
$part2 = trim($part2); //suppression du dernier espace dans la partie de texte restante
echo "<strong>".$part1."</strong> ".$part2;
?>
Donnera :
Lorem Elsass ipsum amet dui jetz gehts los leverwurscht non porta ac baeckeoffe ac bredele
Voilà, encore une petite idée pensée à pas d’heure et après une journée complète de boulot.
J’espère que ces astuces vous serviront 😉
Si vous avez d’autres techniques je suis preneur, c’est du fait maison quand j’avais la tête dans le guidon, donc peut-être qu’il y a beaucoup plus simple ^^
Merci pour votre lecture.
PS : si jamais vous croisez des incohérences n’hésitez pas à me le signaler
merci la ressource, ça pourrai bien me servir.
Pas de problème Arnaud 😉
J’ai fait une petite mise à jour avec l’ajout de la technique offerte par
wordwrap()
.Cette dernière reste à « fonctionnaliser », mais ça semble marcher sur mes premiers tests 🙂
Et en utilisant les Expressions Régulières ?
par ex
preg_match_all('/(\w+)/', 'un deux trois', $a);
=>
$a
contiendraArray
(
[0] => Array (
[0] => un
[1] => deux
[2] => trois
)
[1] => Array (
[0] => un
[1] => deux
[2] => trois
)
)
Oui c’est tout à fait envisageable.
C’est l’avantage de PHP, offrir des solutions à un problème donné 🙂
Si tu le souhaites je peux l’ajouter à l’article, si tu as une fonction qui reprends l’entièreté de ton idée.
Merci pour cette proposition.
ça date mais comme on peut encore tomber dessus. Moi je propose plus simple:
$str = « Suspendisse at magna non lectus lacinia gravida. »;
$str = truncate($str, 40, ‘…’, true);
echo $str; // Suspendisse at magna non lectus…
l’argument true est là pour justement couper au premier espace suivant ♥
et la fonction à coller:
function truncate($string, $max_length = 30, $replacement = », $trunc_at_space = false)
{
$max_length -= strlen($replacement);
$string_length = strlen($string);
if($string_length <= $max_length)
return $string;
if( $trunc_at_space && ($space_position = strrpos($string, ' ', $max_length-$string_length)) )
$max_length = $space_position;
return substr_replace($string, $replacement, $max_length);
}
Hello,
Merci pour ce partage.
Mais si je ne dis pas de bêtise, ça rejoint ma première proposition, et reste plus complexe que la seconde proposée avec
wordwrap()
.Bonnes fêtes !
Une autre version :
function tokenTruncate($string, $your_desired_width) {
$parts = preg_split(‘/([\s\n\r]+)/’, $string, null, PREG_SPLIT_DELIM_CAPTURE);
$parts_count = count($parts);
$length = 0;
$last_part = 0;
for (; $last_part $your_desired_width) { break; }
}
return implode(array_slice($parts, 0, $last_part));
}
Merci beaucoup pour ce script qui vient de me permettre de solutionner le problème que je rencontrais depuis plusieurs jours! Un très très grand MERCI, vraiment!
Yeah \o/
Bonne continuation 🙂
Un peu différente mais correspond à l’idée suivante :
Coupe à l’endroit du premier espace derrière le [nombre]e caractères et ajoute un point de suspension.