En utilisant la fonction Wordwrap . Il divise les textes en plusieurs lignes de telle sorte que la largeur maximale soit celle que vous avez spécifiée, en se coupant aux limites des mots. Après le fractionnement, 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 bord, on devrait faire quelque chose comme:
if (strlen($string) > $your_desired_width)
{
$string = wordwrap($string, $your_desired_width);
$string = substr($string, 0, strpos($string, "\n"));
}
La solution ci-dessus pose le problème de couper prématurément le texte s'il contient une nouvelle ligne avant le point de coupure 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));
}
Aussi, voici 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));
}
}
ÉDITER :
Les caractères UTF8 spéciaux tels que «à» ne sont pas gérés. Ajoutez 'u' à la fin du REGEX pour le gérer:
$parts = preg_split('/([\s\n\r]+)/u', $string, null, PREG_SPLIT_DELIM_CAPTURE);