En utilisant le wordwrap fonction. Elle divise les textes en plusieurs lignes de manière à ce que la largeur maximale soit celle que vous avez spécifiée, avec une rupture aux limites des mots. Après la division, vous prenez simplement la première ligne :
substr($string, 0, strpos(wordwrap($string, $your_desired_width), "\n"));
Une chose que cet oneliner ne gère pas est le cas où le texte lui-même est plus court que la largeur souhaitée. Pour gérer ce cas de figure, il faut faire quelque chose du genre :
if (strlen($string) > $your_desired_width)
{
$string = wordwrap($string, $your_desired_width);
$string = substr($string, 0, strpos($string, "\n"));
}
La solution ci-dessus présente le problème de couper prématurément le texte s'il contient une nouvelle ligne avant le point de coupe réel. Voici une version qui résout ce problème :
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 < $parts_count; ++$last_part) {
$length += strlen($parts[$last_part]);
if ($length > $your_desired_width) { break; }
}
return implode(array_slice($parts, 0, $last_part));
}
Voici également la classe de test PHPUnit utilisée pour tester l'implémentation :
class TokenTruncateTest extends PHPUnit_Framework_TestCase {
public function testBasic() {
$this->assertEquals("1 3 5 7 9 ",
tokenTruncate("1 3 5 7 9 11 14", 10));
}
public function testEmptyString() {
$this->assertEquals("",
tokenTruncate("", 10));
}
public function testShortString() {
$this->assertEquals("1 3",
tokenTruncate("1 3", 10));
}
public function testStringTooLong() {
$this->assertEquals("",
tokenTruncate("toooooooooooolooooong", 10));
}
public function testContainingNewline() {
$this->assertEquals("1 3\n5 7 9 ",
tokenTruncate("1 3\n5 7 9 11 14", 10));
}
}
EDIT :
Les caractères spéciaux UTF8 comme 'à' ne sont pas traités. Ajoutez 'u' à la fin du REGEX pour le gérer :
$parts = preg_split('/([\s\n\r]+)/u', $string, null, PREG_SPLIT_DELIM_CAPTURE);
2 votes
La question vise à dire que le texte tronqué tiendra dans un nombre fixe de pixels sur une page Web. Dans ce cas, selon la police choisie, l'espace requis par caractère n'est pas constant. Nous ne pouvons donc pas supposer que 200 caractères s'adapteront au mieux aux pixels disponibles. Jusqu'à présent (jusqu'au 02-Mar-2011), toutes les réponses ci-dessous manquent ce point et donc aucune d'entre elles ne fournit une solution fiable. - :(
1 votes
Non, pas vraiment. Vous pouvez définir la police de caractères de manière fiable, puis mesurer le pire des scénarios, c'est-à-dire le nombre de caractères les plus larges qui pourraient être insérés. Et si vous avez besoin d'être sûr à 100% de la façon dont le navigateur l'a rendu, ce n'est plus un problème PHP de toute façon.
0 votes
Essayez ce lien, il peut vous aider stackoverflow.com/a/26098951/3944217
0 votes
Vous pourriez trouver
s($str)->truncateSafely(200)
utile, comme on le trouve dans cette bibliothèque autonome .