Smarter word-wrap in PHP for long words?
I've had a go at the custom function for this smart wordwrap:
function smart_wordwrap($string, $width = 75, $break = "\n") { // split on problem words over the line length $pattern = sprintf('/([^ ]{%d,})/', $width); $output = ''; $words = preg_split($pattern, $string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); foreach ($words as $word) { if (false !== strpos($word, ' ')) { // normal behaviour, rebuild the string $output .= $word; } else { // work out how many characters would be on the current line $wrapped = explode($break, wordwrap($output, $width, $break)); $count = $width - (strlen(end($wrapped)) % $width); // fill the current line and add a break $output .= substr($word, 0, $count) . $break; // wrap any remaining characters from the problem word $output .= wordwrap(substr($word, $count), $width, $break, true); } } // wrap the final output return wordwrap($output, $width, $break);}$string = 'hello! too long here too long here too heeeeeeeeeeeeeereisaverylongword but these words are shorterrrrrrrrrrrrrrrrrrrr';echo smart_wordwrap($string, 11) . "\n";
EDIT: Spotted a couple of caveats. One major caveat with this (and also with the native function) is the lack of multibyte support.
How about
$string = "hello! heeeeeeeeeeeeeeereisaverylongword";$break = 25;echo implode(PHP_EOL, str_split($string, $break));
Which outputs
hello! heeeeeeeeeeeeeeere isaverylongword
str_split() converts the string to an array of $break size chunks.
implode() joins the array back together as a string using the glue which in this case is an end of line marker (PHP_EOL) although it could as easily be a '<br/>
'
This is also a solution (for browsers etc.):
$string = 'hello! heeeeeeeeeeeeeeeeeeeeeereisaverylongword';echo preg_replace('/([^\s]{20})(?=[^\s])/', '$1'.'<wbr>', $string);
It puts a <wbr>
at words with 20 or more characters
<wbr>
means "word break opportunity" so it only breaks if it has to (dictated by width of element/browser/viewer/other). It's invisible otherwise.
Good for fluid/responsive layout where there is no fixed width. And does not wrap odd like php's wordwrap