字符串函数
在线手册:中文 英文
PHP手册

wordwrap

(PHP 4 >= 4.0.2, PHP 5)

wordwrap打断字符串为指定数量的字串

说明

string wordwrap ( string $str [, int $width = 75 [, string $break = "\n" [, bool $cut = false ]]] )

使用字符串断点将字符串打断为指定数量的字串。

参数

str

输入字符串。

width

列宽度。

break

使用可选的 break 参数打断字符串。

cut

如果 cut 设置为 TRUE,字符串总是在指定的宽度或者之前位置被打断。因此,如果有的单词宽度超过了给定的宽度,它将被分隔开来。(参见第二个范例)。

返回值

返回打断后的字符串。

更新日志

版本 说明
4.0.3 新增可选的 cut 参数。

范例

Example #1 wordwrap() 范例

<?php
$text 
"The quick brown fox jumped over the lazy dog.";
$newtext wordwrap($text20"<br />\n");

echo 
$newtext;
?>

以上例程会输出:

The quick brown fox<br />
jumped over the lazy<br />
dog.

Example #2 wordwrap() 范例

<?php
$text 
"A very long woooooooooooord.";
$newtext wordwrap($text8"\n"true);

echo 
"$newtext\n";
?>

以上例程会输出:

A very
long
wooooooo
ooooord.

参见


字符串函数
在线手册:中文 英文
PHP手册
PHP手册 - N: 打断字符串为指定数量的字串

用户评论:

ju1ius (18-Feb-2012 11:58)

Another solution to utf-8 safe wordwrap, unsing regular expressions.
Pretty good performance and works in linear time.

<?php
function utf8_wordwrap($string, $width=75, $break="\n", $cut=false)
{
  if(
$cut) {
   
// Match anything 1 to $width chars long followed by whitespace or EOS,
    // otherwise match anything $width chars long
   
$search = '/(.{1,'.$width.'})(?:\s|$)|(.{'.$width.'})/uS';
   
$replace = '$1$2'.$break;
  } else {
   
// Anchor the beginning of the pattern with a lookahead
    // to avoid crazy backtracking when words are longer than $width
   
$pattern = '/(?=\s)(.{1,'.$width.'})(?:\s|$)/uS';
   
$replace = '$1'.$break;
  }
  return
preg_replace($search, $replace, $string);
}
?>
Of course don't forget to use preg_quote on the $width and $break parameters if they come from untrusted input.

mail at dasprids dot de (09-Oct-2011 01:35)

A completly working, multibyte-safe, version of wordwrap (as I contributed it to the Zend Framework in Zend_Text_MultiByte). It's mostly a port of the original PHP wordwrap function, backed by a lot of unit tests:

<?php
/**
 * Word wrap
 *
 * @param  string  $string
 * @param  integer $width
 * @param  string  $break
 * @param  boolean $cut
 * @param  string  $charset
 * @return string
 */
function iconv_wordwrap($string, $width = 75, $break = "\n", $cut = false, $charset = 'utf-8')
{
   
$stringWidth = iconv_strlen($string, $charset);
   
$breakWidth  = iconv_strlen($break, $charset);

    if (
strlen($string) === 0) {
        return
'';
    } elseif (
$breakWidth === null) {
        throw new
Zend_Text_Exception('Break string cannot be empty');
    } elseif (
$width === 0 && $cut) {
        throw new
Zend_Text_Exception('Can\'t force cut when width is zero');
    }

   
$result    = '';
   
$lastStart = $lastSpace = 0;

    for (
$current = 0; $current < $stringWidth; $current++) {
       
$char = iconv_substr($string, $current, 1, $charset);

        if (
$breakWidth === 1) {
           
$possibleBreak = $char;
        } else {
           
$possibleBreak = iconv_substr($string, $current, $breakWidth, $charset);
        }

        if (
$possibleBreak === $break) {
           
$result    .= iconv_substr($string, $lastStart, $current - $lastStart + $breakWidth, $charset);
           
$current   += $breakWidth - 1;
           
$lastStart  = $lastSpace = $current + 1;
        } elseif (
$char === ' ') {
            if (
$current - $lastStart >= $width) {
               
$result    .= iconv_substr($string, $lastStart, $current - $lastStart, $charset) . $break;
               
$lastStart  = $current + 1;
            }

           
$lastSpace = $current;
        } elseif (
$current - $lastStart >= $width && $cut && $lastStart >= $lastSpace) {
           
$result    .= iconv_substr($string, $lastStart, $current - $lastStart, $charset) . $break;
           
$lastStart  = $lastSpace = $current;
        } elseif (
$current - $lastStart >= $width && $lastStart < $lastSpace) {
           
$result    .= iconv_substr($string, $lastStart, $lastSpace - $lastStart, $charset) . $break;
           
$lastStart  = $lastSpace = $lastSpace + 1;
        }
    }

    if (
$lastStart !== $current) {
       
$result .= iconv_substr($string, $lastStart, $current - $lastStart, $charset);
    }

    return
$result;
}
?>

paul at preinheimer dot com (26-Sep-2011 12:04)

If your goal is to allow a browser to word-wrap nicely, while maintaining a fluid layout, you'll want to break with: &#8203

It's a zero width space character: http://en.wikipedia.org/wiki/Zero-width_space

This way the browser can break where it needs to, without adding a visual distraction of spaces within the text.

e.g.
<?php
//Using &#8203; here allows the browser to break the line of text, without the visual distraction.
$line = wordwrap($line, 10, "&#8203;", true);
?>

#PROTIP: leave a comment, so the next person to read your code has a clue what you've done.

info at hsdn dot org (08-Jul-2011 04:41)

Wordwrap with UTF-8 supports, returns as array.

<?php

function mb_wordwrap_array($string, $width)
{
    if ((
$len = mb_strlen($string, 'UTF-8')) <= $width)
    {
        return array(
$string);
    }

   
$return = array();
   
$last_space = FALSE;
   
$i = 0;

    do
    {
        if (
mb_substr($string, $i, 1, 'UTF-8') == ' ')
        {
           
$last_space = $i;
        }

        if (
$i > $width)
        {
           
$last_space = ($last_space == 0) ? $width : $last_space;
   
           
$return[] = trim(mb_substr($string, 0, $last_space, 'UTF-8'));
           
$string = mb_substr($string, $last_space, $len, 'UTF-8');
           
$len = mb_strlen($string, 'UTF-8');
           
$i = 0;
        }

       
$i++;
    }
    while (
$i < $len);

   
$return[] = trim($string);

    return
$return;
}

?>

dynastoned (09-Jun-2011 01:08)

I wrote this because people leaving comments would spam or make words that were too long and it was breaking the tables in my design.

So for instance if someone wanted to type "hahahhahahahhahahhahahhahahhahahahhaha" it would go past the specified table width and break the design.

To curb this problem I needed a way to break words that were longer than 15 characters in length.  So I figured if I added a space every 15 characters that would solve my problem.  This is how I did it.

Example:

<?php

// comment the user left
$comment = "hi im here to break your page bahahahhahahhahhahhahahha.  i hope this makes you mad lolllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll.";

// breaking down each word in the $comment into arrays using explode().
$array = explode(" ", $comment);

// here i used the for loop to enable me to run each word one by one through wordwrap() and add a space into the word if it is longer than 15 characters.
for ($i = 0, $array_num = count($array); $i < $array_num; $i++) {
   
$word_split = wordwrap($array[$i], 15, " ", true);
    echo
"$word_split ";
}

// result = hi im here to break your page bahahahhahahhah hahhahahha. i hope this makes you mad lolllllllllllll lllllllllllllll lllllllllllllll lllllllllllllll lllllllll.

?>

mulllhausen (28-Apr-2011 08:16)

here is another function acts like wordwrap but ignores html tags. it basically takes out all the tags from the string, wordwrappes the string, then puts the tags back in. enjoy ;)

<?php

function html_wordwrap($str, $width = 75, $break = "\n", $cut = false)
{
   
//same functionality as wordwrap, but ignore html tags
   
$unused_char = find_unused_char($str); //get a single character that is not used in the string
   
$tags_arr = get_tags_array($str);
   
$q = '?';
   
$str1 = ''; //the string to be wrapped (will not contain tags)
   
$element_lengths = array(); //an array containing the string lengths of each element
   
foreach($tags_arr as $tag_or_words)
    {
        if(
preg_match("/<.*$q>/", $tag_or_words)) continue;
       
$str1 .= $tag_or_words;
       
$element_lengths[] = strlen($tag_or_words);
    }
   
$str1 = wordwrap($str1, $width, $unused_char, $cut);
    foreach(
$tags_arr as &$tag_or_words)
    {
        if(
preg_match("/<.*$q>/", $tag_or_words)) continue;
       
$tag_or_words = substr($str1, 0, $element_lengths[0]);
       
$str1 = substr($str1, $element_lengths[0]);
       
array_shift($element_lengths); //delete the first array element - we have used it now so we do not need it
   
}
   
$str2 = implode('', $tags_arr);
   
$str3 = str_replace($unused_char, $break, $str2);
    return
$str3;
}
function
get_tags_array($str)
{
   
//given a string, return a sequential array with html tags in their own elements
   
$q = '?';
    return
preg_split("/(<.*$q>)/",$str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
}
function
find_unused_char($str)
{
   
//find an unused character in a string
   
$possible_chars = array('|', '!', '@', '#', '$', '%', '^', '&', '*', '~');
    foreach(
$possible_chars as $char) if(strpos($str, $char) === false) return $char;
    die(
'you must add another SINGLE unused character, not one of [|!@#$%^&*~], to the $possible_chars array in function find_unused_char');
}

?>

altin_bardhi at yahoo dot co dot uk (28-Jan-2011 12:03)

Here I have come out with a possibly very useful wordwrap code snippet.

Apparently what this piece of code does is: it takes the entered text and looks for words longer than the defined ‘$chunk_length’ if it finds any, it splits the long words and then it concatenates the whole string back to a new string with longer words separated by a dash character in this case.

After it has accomplished this task it then inserts an HTML line break after a specified ‘$line_length’ (Depending on your containers width requirements)

<?php

//Start function explode_ wrap
function explode_wrap($text, $chunk_length, $line_length){

//Explode all the words separated by spaces in a string
$string_chunks = explode(' ', $text);

// Get each split word from the array $sring_chunks_array => key => value
foreach ($string_chunks as $chunk => $value) {

if(
strlen($value) >= $chunk_length){

//Split the chunks/words which are longer than $chunk_length
$new_string_chunks[$chunk] = chunk_split($value, $chunk_length, ' - ');

}else {

//Do not split the normal length words
$new_string_chunks[$chunk] = $value;

}

}
//End foreach loop

//Concatenate back the all the words
$new_text=implode(' ', $new_string_chunks);

return
wordwrap($new_text, $line_length, '<br />');

}
//End function

?>

holdoffhunger at gmail dot com (12-Dec-2010 05:47)

Say you have a string you want to output to the user, but you want to wordwrap the words with WBR and ampersand-shy-semicolon tags.  This will cause the word to break in half in HTML, instead of causing the page to be huge in width.  This is extremely useful for displaying full link URLs, as many of them run on forever, and in PHP-BB, that means an entire thread will look ugly, because of one guy posting a link.  On the other hand, both the WBR and ampersand-shy-semicolon tags ignore any spaces near them.  That means, if you parsed all your PHP-BB inputted data, a sentence would like this: "Thisisasentence."  It effectively cuts out the spaces.  The solution?  Do an str_replace, finding every " " (one space) and replacing it with ("  ") spaces, and then wordwrap the entire string with WBR/shy tags, every four spaces.  This guarantees that spaces within HTML will be recognized properly in all browsers, while also guaranteeing that no words will fail to wordwrap.

nbenitezl[arroba]gmail[dot]com (02-Dec-2010 12:56)

Hi, this function is like wordwrap but it ignores html tags, it works like wordwrap when called with fourth parameter as true. It's based on a function I find here but improved to closer match the output of wordwrap (i.e. removed spaces at start of line) and also to improve performance.

Hope it can be useful for you :-)
<?php
function htmlwrap(&$str, $maxLength, $char='<br />'){
   
$count = 0;
   
$newStr = '';
   
$openTag = false;
   
$lenstr = strlen($str);
    for(
$i=0; $i<$lenstr; $i++){
       
$newStr .= $str{$i};
        if(
$str{$i} == '<'){
           
$openTag = true;
            continue;
        }
        if((
$openTag) && ($str{$i} == '>')){
           
$openTag = false;
            continue;
        }
        if(!
$openTag){
            if(
$str{$i} == ' '){
                if (
$count == 0) {
                   
$newStr = substr($newStr,0, -1);
                    continue;
                } else {
                   
$lastspace = $count + 1;
                }
            }
           
$count++;
            if(
$count==$maxLength){
                if (
$str{$i+1} != ' ' && $lastspace && ($lastspace < $count)) {
                   
$tmp = ($count - $lastspace)* -1;
                   
$newStr = substr($newStr,0, $tmp) . $char . substr($newStr,$tmp);
                   
$count = $tmp * -1;
                } else {
                   
$newStr .= $char;
                   
$count = 0;
                }
               
$lastspace = 0;
            }
        } 
    }

    return
$newStr;
}
?>

venimus at gmail dot com (09-Sep-2010 10:21)

To cut long texts up to certain length without breaking words you can use this simple function

<?php

function cutstr($str, $length, $ellipsis=''){
  
$cut=(array)explode('\n\n',wordwrap($str),$length,'\n\n'));
   return
$cut[0].((strlen($cut)<strlen($str))?$ellipsis:'');
}

?>

Third parameter is added to the output string if it was cut, usually you should use '...'

Sam B (02-Jul-2010 04:41)

The multibyte wordwrap functions in the comments all seem to break in the middle of word.  This one should break on spaces, where possible.

<?php
/**
 * Multibyte capable wordwrap
 *
 * @param string $str
 * @param int $width
 * @param string $break
 * @return string
 */
function mb_wordwrap($str, $width=74, $break="\r\n")
{
   
// Return short or empty strings untouched
   
if(empty($str) || mb_strlen($str, 'UTF-8') <= $width)
        return
$str;
  
   
$br_width  = mb_strlen($break, 'UTF-8');
   
$str_width = mb_strlen($str, 'UTF-8');
   
$return = '';
   
$last_space = false;
   
    for(
$i=0, $count=0; $i < $str_width; $i++, $count++)
    {
       
// If we're at a break
       
if (mb_substr($str, $i, $br_width, 'UTF-8') == $break)
        {
           
$count = 0;
           
$return .= mb_substr($str, $i, $br_width, 'UTF-8');
           
$i += $br_width - 1;
            continue;
        }

       
// Keep a track of the most recent possible break point
       
if(mb_substr($str, $i, 1, 'UTF-8') == " ")
        {
           
$last_space = $i;
        }

       
// It's time to wrap
       
if ($count > $width)
        {
           
// There are no spaces to break on!  Going to truncate :(
           
if(!$last_space)
            {
               
$return .= $break;
               
$count = 0;
            }
            else
            {
               
// Work out how far back the last space was
               
$drop = $i - $last_space;

               
// Cutting zero chars results in an empty string, so don't do that
               
if($drop > 0)
                {
                   
$return = mb_substr($return, 0, -$drop);
                }
               
               
// Add a break
               
$return .= $break;

               
// Update pointers
               
$i = $last_space + ($br_width - 1);
               
$last_space = false;
               
$count = 0;
            }
        }

       
// Add character from the input string to the output
       
$return .= mb_substr($str, $i, 1, 'UTF-8');
    }
    return
$return;
}
?>

Ivan Lisnik (11-Jun-2010 11:26)

here is my example of UTF-8 wordwrap
<?php
function wordwrap($str, $width, $break)
{
   
$return = '';
   
$br_width = mb_strlen($break, 'UTF-8');
    for(
$i = 0, $count = 0; $i < mb_strlen($str, 'UTF-8'); $i++, $count++)
    {
        if (
mb_substr($str, $i, $br_width, 'UTF-8') == $break)
        {
           
$count = 0;
           
$return .= mb_substr($str, $i, $br_width, 'UTF-8');
           
$i += $br_width - 1;
        }
       
        if (
$count > $width)
        {
           
$return .= $break;
           
$count = 0;
        }
       
       
$return .= mb_substr($str, $i, 1, 'UTF-8');
    }
   
    return
$return;
}
?>

kouber at php dot net (27-May-2010 10:34)

If you need a function to cut only words longer than N characters, feel free to use the function below:

<?php
function wrap($str, $width=75, $break="\n") {
  return
preg_replace('#(\S{'.$width.',})#e', "chunk_split('$1', ".$width.", '".$break."')", $str);
}

echo
wrap('aaaa bbb cc dddd-dddd', 3, ' ');
?>

The above example will output: "aaa a  bbb  cc ddd d-d ddd "

Lourvestruck at hotmail dot com (16-Apr-2010 10:19)

I have a page with an image floating on the right, and text printed out beside the image (to the left). I used wordwrap to wrap the text so that it doesn't go over the image, but sometimes the text would go down beyond the image (vertically beyond the image, where the height of the text was more than the height of the image), resulting in wrapped text that doesn't need to be wrapped. So I came up with this method that takes a number max-lines to wordwrap, and then the rest either no wrapping, or wordwrapping at a different number of characters:

<?php
// Wrap the text so it fits within the 35c width (to fit beside the picture)
$text = wordwrap($text, 35, "<br/>");

// The text comes below the picture, where we want wrapping to stop...
$maxLines = 18;
$newWidth = 80;
$lastPos = 1;
for (
$i=0;$i<$maxLines;$i++)
{
   
$lastPos = strpos($text, '<br/>', $lastPos+1);   
    if (
$lastPos === FALSE)
        break;
}

$text = substr($text, 0, $lastPos) . "<br/>" . wordwrap(str_replace('<br/>',' ',substr($text, $lastPos)), $newWidth, '<br/>');

print
$text;
?>

homer2k at gmx dot net (30-Mar-2010 12:31)

A function that considers URIs.
<?php
function wordwrapURI($str, $width = 75, $break = "\n", $cut = false)
{
   
$newText = array();
   
$words = explode(' ', str_replace("\n", "\n ", $str));
    foreach(
$words as $word) {
        if(
strpos($word, 'http://') === false && strpos($word, 'www.') === false) {
           
$word = wordwrap($word, $width, $break, $cut);
        }
       
$newText[] = $word;
    }
    return
implode(' ', $newText);
}
?>

mary dot kalinosky at thieme dot com (18-Nov-2009 11:29)

I wish there were a word_unwrap() function, but this seems to work:

<?php $text = preg_replace('/[\t\r\n]+/', ' ', $text); ?>

andrnag at yandex dot ru (06-Nov-2009 06:28)

This is a really working multibite wordwrap function. Teted on utf-8 English and Russian strings. It's a compilation on other functions represented here.
<?php
  
function utf8_wordwrap($str, $width = 75, $break = "\n") // wordwrap() with utf-8 support
   
{
       
$str preg_split('/([\x20\r\n\t]++|\xc2\xa0)/sSX', $str, -1, PREG_SPLIT_NO_EMPTY);
       
$len = 0;
        foreach (
$str as $val)
        {
           
$val .= ' ';
           
$tmp = mb_strlen($val, 'utf-8');
           
$len += $tmp;
            if (
$len >= $width)
            {
               
$return .= $break . $val;
               
$len = $tmp;
            }
            else
               
$return .= $val;
        }
        return
$return;
    }
?>

ojs-hp at web dot de (30-Oct-2009 06:06)

After I got some problems with my function to convert a BB-text into HTML. Long words didn't really fit into the layout and only wordwarp() also added breaks to words which would fit into the layout or destroy the other HTML-tags....
So this is my solution. Only words with strlen() >= 40 are edited with wordwarp().

<?php
function bb2html($bb) {
       
$words= explode(' ', $bb); // string to array
   
foreach ($words as $word) {
       
$break = 0;
        for (
$i = 0; $i < strlen($word); $i++) {
            if (
$break >= 40) {
               
$word= wordwrap($word, 40, '-<br>', true); //add <br> every 40 chars
               
$break = 0;
            }
           
$break++;

        }
       
$newText[] = $word; //add word to array
   
}
   
$bb = implode(' ', $newText); //array to string
   
return $bb;
}
?>

starfantasy84 at hotmail dot com (30-Jul-2009 06:16)

I tried using mb functions to word wrap 10 long strings (200 unicode utf8 chars) and I hit execution timeout error. After searching and testing, I came up with this simple and fast function for unicode word wrap.

<?php
//function to break up strings without whitespace chars in between
//if $cut is true then strings will be forcefully break up even there are whitespace in between.
function unicode_wordwrap($str, $len=50, $break=" ", $cut=false){
    if(empty(
$str)) return "";
   
   
$pattern="";
    if(!
$cut)
       
$pattern="/(\S{".$len."})/u";
    else
       
$pattern="/(.{".$len."})/u";
   
    return
preg_replace($pattern, "\${1}".$break, $str);
}
?>

Marcin Dobruk [zuku3000 at yahoo dot co dot uk] (15-Jun-2009 10:21)

Word wrap from left to right (standard) and from right to left.

<?php
function myWordWrap ($string, $length=3, $wrap=',', $from='left') {
    if (
$from=='left') $txt=wordwrap($string, $length, $wrap, true);
    if (
$from=='right') {
       
// string to array
       
$arr_l=array();
        for (
$a=0;strlen($string)>$a;$a++) $arr_l[$a]=$string{$a};
       
// reverse array
       
$arr_r=array_reverse($arr_l);
       
// array to string
       
$string_r='';
        foreach (
$arr_r as $arr_line => $arr) $string_r.=$arr;
       
// add wrap to reverse string
       
$string_r=wordwrap($string_r, $length, $wrap, true);
       
// reverse string to array
       
$arr_r=array();
        for (
$a=0;strlen($string_r)>$a;$a++) $arr_r[]=$string_r{$a};
       
// reverse array again
       
$arr_l=array_reverse($arr_r);
       
// string with wrap
       
$txt='';
        foreach (
$arr_l as $arr_line => $arr) $txt.=$arr;
        }
    return
$txt;
    }
?>

r dot hartung at roberthartung dot de (23-Mar-2009 12:26)

I was wondering about my CMS to break up code but only non-HTML code - I didn't found anything so I came up with this little solution:

<?php
function wordWrapIgnoreHTML($string, $length = 45, $wrapString = "\n")
   {
    
$wrapped = '';
    
$word = '';
    
$html = false;
    
$string = (string) $string;
     for(
$i=0;$i<strlen($string);$i+=1)
     {
      
$char = $string[$i];
      
      
/** HTML Begins */
      
if($char === '<')
       {
         if(!empty(
$word))
         {
          
$wrapped .= $word;
          
$word = '';
         }
        
        
$html = true;
        
$wrapped .= $char;
       }
      
      
/** HTML ends */
      
elseif($char === '>')
       {
        
$html = false;
        
$wrapped .= $char;
       }
      
      
/** If this is inside HTML -> append to the wrapped string */
      
elseif($html)
       {
        
$wrapped .= $char;
       }
      
      
/** Whitespace characted / new line */
      
elseif($char === ' ' || $char === "\t" || $char === "\n")
       {
        
$wrapped .= $word.$char;
        
$word = '';
       }
      
      
/** Check chars */
      
else
       {
        
$word .= $char;
        
         if(
strlen($word) > $length)
         {
          
$wrapped .= $word.$wrapString;
          
$word = '';
         }
       }
     }

    if(
$word !== ''){
       
$wrapped .= $word;
    }
    
     return
$wrapped;
   }

$str = '<a href="http://www.example.de">';
$str .= 'Test-STRRRRRRRRRRRRRRRRRRIIIIIIIIIIIIIIIIIIIIIIING</a>';
$str .= '<!-- COMMENT_INSIDE_ANOTHER';
$str .= '_LONG_STRING //-->';

echo
wordWrapIgnoreHTML($str, 25, '[BREAK]');

// Output: <a href="http://www.roberthartung.de">
// Test-STRRRRRRRRRRRRRRRRRRI[BREAK]
// IIIIIIIIIIIIIIIIIIIIIING
// </a><!-- ... //-->
?>


[NOTE BY danbrown AT php DOT net: Contains a bug fix provided by (jaw AT condidact DOT dk) on 02-APR-09 to address an issue where "the last word in a non-html-wrapped string will be omitted."]

Matt at newbiewebdevelopment dot idk (04-Mar-2009 09:53)

My version of multibyte wordwrap

<?php
function mb_wordwrap($string, $width=75, $break="\n", $cut = false) {
    if (!
$cut) {
       
$regexp = '#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){'.$width.',}\b#U';
    } else {
       
$regexp = '#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){'.$width.'}#';
    }
   
$string_length = mb_strlen($string,'UTF-8');
   
$cut_length = ceil($string_length / $width);
   
$i = 1;
   
$return = '';
    while (
$i < $cut_length) {
       
preg_match($regexp, $string,$matches);
       
$new_string = $matches[0];
       
$return .= $new_string.$break;
       
$string = substr($string, strlen($new_string));
       
$i++;
    }
    return
$return.$string;
}

$mb_string = "こんにちは";//Hello in Japanese
$cut_mb_string = mb_wordwrap($mb_string,1," ",true); //こ ん に ち は
print($cut_mb_string);
?>

admin at studio-gepard dot pl (09-Dec-2008 01:09)

<?php
function substr_word($str, $start, $end) {
   
//function taking sub string from $str in between $start chars and $end chars.

   
$String = wordwrap($str, ($end - $start), '[cut]', false);   //add [cut] for each word after $end chars
   
$ExplodedString = explode('[cut]', $String);      //make an array with elements long for $end chars
   
$end=ceil(strlen($text)/$end);   //how many elements of array are there. (celi > round >floor)

   
$i=floor($end/$start);                            //take an element with start position

   
$String = $ExplodedString[$i];
    if (
$String[0]==" ") { substr($String, 1); } if ($String[0]==" ") { substr($String, 1); } if ($String[0]==" ") { substr($String, 1); }

    return
$String;
}
?>
Usage example:
<?php
  
   $from
=strpos($text,$word)-100;
  
$to=strpos($text,$word)+400;
  
$text=substrpos($text, $from, $to);

?>
will return text 100 chars before and 400 chars after searched word without breaking the words in text.
Good for seach scirpts for your website - imagine that $word is keyword you search for.

[NOTE BY danbrown AT php DOT net:  Contains a fix provided by (admin AT studio-gepard DOT pl).]

php at maranelda dot org (16-Sep-2008 12:17)

Anyone attempting to write a text email client should be aware of the following:

<?php

$a
= "some text that must wrap nice";

$a = wordwrap($a, 9);

echo
$a;

//  some text
//  that must
//  wrap nice

$a = wordwrap($a, 9);

echo
$a;

//  some text
//  that
//  must
//  wrap
//  nice

?>

Subsequent uses of wordwrap() on already wrapped text will take the end-of-line characters into account when working out line length, thus reading each line that just fit nicely the first time around as being one character too long the second. This can be a problem when preparing a text email that contains (eg.) a forwarded email which has already been word-wrapped.

Solutions below which explode() the text on end-of-lines and wordwrap() the resulting strings separately take care of this nicely.

mn_nospamplz_bayazit at g_mail dot com (31-Aug-2008 02:21)

This should wrap long lines of code, maintaining the proper level of indentation, plus an extra tab to indicate it's been wrapped.

<?php
function codewrap($code, $maxLength = 80)
{
   
$lines = explode("\n", $code);
   
$count = count($lines);
    for(
$i=0; $i<$count; ++$i) {
       
preg_match('`^\s*`', $code, $matches);
       
$lines[$i] = wordwrap($lines[$i], $maxLength, "\n$matches[0]\t");
    }
    return
implode("\n", $lines);
}
?>

mathijs DOT van DOT veluw AT SMScity.com (28-May-2008 12:56)

I needed an UTF8/Unicode compatible wordwrap with the same features.
As i searched the internet several times, and havent found anything. I created one my self.

<?php
   
public static function utf8Wordwrap($str, $width=75, $break="\n", $cut=false)
    {
       
$splitedArray    = array();
       
$lines            = explode("\n", $str);
        foreach (
$lines as $line) {
           
$lineLength = strlen($line);
            if (
$lineLength > $width) {
               
$words = explode("\040", $line);
               
$lineByWords = '';
               
$addNewLine = true;
                foreach (
$words as $word) {
                   
$lineByWordsLength        = strlen($lineByWords);
                   
$tmpLine                = $lineByWords.((strlen($lineByWords) !== 0) ? ' ' : '').$word;
                   
$tmplineByWordsLength    = strlen($tmpLine);
                    if (
$tmplineByWordsLength > $width && $lineByWordsLength <= $width && $lineByWordsLength !== 0) {
                       
$splitedArray[]    = $lineByWords;
                       
$lineByWords    = '';
                    }

                   
$newLineByWords            = $lineByWords.((strlen($lineByWords) !== 0) ? ' ' : '').$word;
                   
$newLineByWordsLength    = strlen($newLineByWords);
                    if (
$cut && $newLineByWordsLength > $width) {
                        for (
$i = 0; $i < $newLineByWordsLength; $i = $i + $width) {
                           
$splitedArray[] = mb_substr($newLineByWords, $i, $width);
                        }
                       
$addNewLine = false;
                    } else {
                       
$lineByWords = $newLineByWords;
                    }
                }
                if (
$addNewLine) {
                   
$splitedArray[] = $lineByWords;
                }
            } else {
               
$splitedArray[] = $line;
            }
        }
        return
implode($break, $splitedArray);
    }
?>

Hope someone else can use this also.
(Also all improvements are welcome)

admin at jcink dot com (25-Apr-2008 09:56)

I wanted something that would word wrap just one word. People were doing ffffffffffffffffff in my comments page on my site, annoyingly stretching the page. but I didn't want to wrap at a certain fixed length, just wanted to break up words like that only. Here's what I came up with if anyone wants it.

<?php
function one_wordwrap($string,$width){
 
$s=explode(" ", $string);
  foreach (
$s as $k=>$v) {
   
$cnt=strlen($v);
    if(
$cnt>$width) $v=wordwrap($v, $width, "<br />", true);
     
$new_string.="$v ";
  }
  return
$new_string;
}
?>

$del=' at '; 'sanneschaap' dot $del dot 'gmail dot com' (17-Apr-2008 09:41)

These functions let you wrap strings comparing to their actual displaying width of proportional font. In this case Arial, 11px. Very handy in some cases since CSS3 is not yet completely supported. 100 strings = ~5 ms

My old sheep word wrap function (posted at the bottom of this page, is kinda old dated and this one is faster and more accurate).

<?php
//the width of the biggest char @
$fontwidth = 11;

//each chargroup has char-ords that have the same proportional displaying width
$chargroup[0] = array(64);
$chargroup[1] = array(37,87,119);
$chargroup[2] = array(65,71,77,79,81,86,89,109);
$chargroup[3] = array(38,66,67,68,72,75,78,82,83,85,88,90);
$chargroup[4] = array(35,36,43,48,49,50,51,52,53,54,55,56,57,60,61,62,63, 69,70,76,80,84,95,97,98,99,100,101,103,104,110,111,112, 113,115,117,118,120,121,122,126);
$chargroup[5] = array(74,94,107);
$chargroup[6] = array(34,40,41,42,45,96,102,114,123,125);
$chargroup[7] = array(44,46,47,58,59,91,92,93,116);
$chargroup[8] = array(33,39,73,105,106,108,124);
   
//how the displaying width are compared to the biggest char width
$chargroup_relwidth[0] = 1; //is char @
$chargroup_relwidth[1] = 0.909413854;
$chargroup_relwidth[2] = 0.728241563;
$chargroup_relwidth[3] = 0.637655417;
$chargroup_relwidth[4] = 0.547069272;
$chargroup_relwidth[5] = 0.456483126;
$chargroup_relwidth[6] = 0.36589698;
$chargroup_relwidth[7] = 0.275310835;
$chargroup_relwidth[8] = 0.184724689;

//build fast array
$char_relwidth = null;
for (
$i=0;$i<count($chargroup);$i++){
    for (
$j=0;$j<count($chargroup[$i]);$j++){
       
$char_relwidth[$chargroup[$i][$j]] = $chargroup_relwidth[$i];
    }
}

//get the display width (in pixels) of a string
function get_str_width($str){
    global
$fontwidth,$char_relwidth;
   
$result = 0;
    for (
$i=0;$i<strlen($str);$i++){
       
$result += $char_relwidth[ord($str[$i])];
    }
   
$result = $result * $fontwidth;
    return
$result;   
}

//truncates a string at a certain displaying pixel width
function truncate_str_at_width($str, $width, $trunstr='...'){
    global
$fontwidth,$char_relwidth;       
   
$trunstr_width = get_str_width($trunstr);
   
$width -= $trunstr_width;
   
$width = $width/$fontwidth;
   
$w = 0;
    for (
$i=0;$i<strlen($str);$i++){
       
$w += $char_relwidth[ord($str[$i])];
        if (
$w > $width)
            break;   
    }
   
$result = substr($str,0,$i).$trunstr;
    return
$result;
   
// texas is the reason rules at 10am :)
}
?>

joachim (16-Apr-2008 10:42)

There seems to be a difference between php 5.1 and 5.2 in how wordwrap counts characters (all on Mac OSX 10.5.2):

/Applications/MAMP/bin/php5/bin/php --version
PHP 5.1.6 (cli) (built: Sep  8 2006 10:25:04)

/Applications/MAMP/bin/php5/bin/php -r 'echo wordwrap("In aller Freundschaft (50)_UT", 20) . "\n";'
In aller
Freundschaft
(50)_UT

php --version
PHP 5.2.5 (cli) (built: Feb 20 2008 12:30:47)

php -r 'echo wordwrap("In aller Freundschaft (50)_UT", 20) . "\n";'
In aller
Freundschaft (50)_UT

thomas at tgohome dot com (19-Feb-2008 08:21)

I wrote a justification function for a project of mine. It uses the wordwrap function and provides four justification options:

* Left; typically, the leftmost words receive the most padding
* Right; vice versa; the rightmost words receive the most padding
* Both; tries to evenly distribute the padding among leftmost and rightmost words
* Average; most complicated, uses an average of the three previous algorithms. I'd say this one produces the best result as it's more distributed in the center.

It does not justify the last line.

<?php
define
('JPAD_LEFT', 1);     // More spaces are added on the left of the line
define('JPAD_RIGHT', 2);    // More spaces are added on the right of the line
define('JPAD_BOTH', 4);     // Tries to evenly distribute the padding
define('JPAD_AVERAGE', 8);  // Tries to position based on a mix of the three algorithms

function justify($input, $width, $mode = JPAD_AVERAGE)
{
   
// We want to have n characters wide of text per line.
    // Use PHP's wordwrap feature to give us a rough estimate.
   
$justified = wordwrap($input, $width, "\n", false);
   
$justified = explode("\n", $justified);
   
   
// Check each line is the required width. If not, pad
    // it with spaces between words.
   
foreach($justified as $line)
    {
        if(
strlen($line) != $width)
        {
           
// Split by word, then glue together
           
$words = explode(' ', $line);
           
$diff  = $width - strlen($line);
           
            while(
$diff > 0)
            {   
               
// Process the word at this diff
               
if     ($mode == JPAD_BOTH$words[$diff / count($words)] .= ' ';
                else if(
$mode == JPAD_AVERAGE
                   
$words[(($diff / count($words)) +
                            (
$diff % count($words)) +
                            (
count($words) - ($diff % count($words))))
                            /
3] .= ' ';
                else if(
$mode == JPAD_LEFT$words[$diff % count($words)] .= ' ';
                else if(
$mode == JPAD_RIGHT) $words[count($words) - ($diff % count($words))] .= ' ';
               
               
// Next diff, please...
               
$diff--;
            }
        }
        else
        {
           
$words = explode(' ', $line);
        }
       
       
$final .= implode(' '$words) . "\n";
    }
   
   
// Return the final string
   
return $final;
}
?>

Examples of output for the average algorithm:

Lorem ipsum dolor            sit amet, consectetur
adipisicing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud  exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in    reprehenderit in voluptate velit
esse cillum dolore       eu fugiat nulla pariatur.
Excepteur sint occaecat    cupidatat non proident,
sunt in culpa qui  officia deserunt mollit anim id
est laborum.          

(50 characters wide)

golanzakaiATpatternDOTcoDOTil (08-Oct-2007 06:39)

<?php
   
/**
     * Wordwrap without unnecessary word splitting using multibyte string functions
     *
     * @param string $str
     * @param int $width
     * @param string $break
     * @return string
     * @author Golan Zakai <golanzakaiATpatternDOTcoDOTil>
     */
   
function _wordwrap( $str, $width, $break ) {
       
$formatted = '';
       
$position = -1;
       
$prev_position = 0;
       
$last_line = -1;
       
       
/// looping the string stop at each space
       
while( $position = mb_stripos( $str, " ", ++$position, 'utf-8' ) ) {
            if(
$position > $last_line + $width + 1 ) {
               
$formatted.= mb_substr( $str, $last_line + 1, $prev_position - $last_line - 1, 'utf-8' ).$break;
               
$last_line = $prev_position;
            }
           
$prev_position = $position;
        }
       
       
/// adding last line without the break
       
$formatted.= mb_substr( $str, $last_line + 1, mb_strlen( $str ), 'utf-8' );
        return
$formatted;
    }
?>

fatchris (29-Jun-2007 10:11)

If your string has some html entities, then it might split one in half. e.g.

<?php
/*
Outputs (Renders):

Préf&-
eacute;rence-
s e-mails

*/

echo wordwrap("Pr&eacute;f&eacute;rences e-mails");

?>

To solve this, you can use the following function:

<?php

function wordwrap2( $str, $width = 75, $break = '\n', $cut = true ) {
 
$str = html_entity_decode( $str ); //first decode
 
$out = wordwrap( $str, $width, $break, $cut ); //now wordwrap
 
$out = htmlentities( $out ); //re-encode the entities
 
$out = str_replace( htmlentities( $break ), $break, $out ); //put back the break
 
return $out;
}

?>

phpsales at gmail dot com (16-May-2007 05:53)

<?php
########################################
# Break long words with out cutting HTML tags.
########################################

/* Break Long Words (string, int, char) */

function breakLongWords($str, $maxLength, $char){
   
$wordEndChars = array(" ", "\n", "\r", "\f", "\v", "\0");
   
$count = 0;
   
$newStr = "";
   
$openTag = false;
    for(
$i=0; $i<strlen($str); $i++){
       
$newStr .= $str{$i};   
       
        if(
$str{$i} == "<"){
           
$openTag = true;
            continue;
        }
        if((
$openTag) && ($str{$i} == ">")){
           
$openTag = false;
            continue;
        }
       
        if(!
$openTag){
            if(!
in_array($str{$i}, $wordEndChars)){//If not word ending char
               
$count++;
                if(
$count==$maxLength){//if current word max length is reached
                   
$newStr .= $char;//insert word break char
                   
$count = 0;
                }
            }else{
//Else char is word ending, reset word char count
                   
$count = 0;
            }
        }
       
    }
//End for   
   
return $newStr;
}
?>

Rekcor (27-Mar-2007 02:36)

Improved version of egyptechno[at]gmail.com's wordCut.

In this improved function, the length of $sMessage is taken into consideration while cutting the text, so the returned string is never longer than $iMaxLength. Besides that, whole words are cut as well.

<?php
/**
 * function wordCut($sText, $iMaxLength, $sMessage)
 *
 * + cuts an wordt after $iMaxLength characters
 *
 * @param  string   $sText       the text to cut
 * @param  integer  $iMaxLength  the text's maximum length
 * @param  string   $sMessage    piece of text which is added to the cut text, e.g. '...read more'
 *
 * @returns string
 **/    
function wordCut($sText, $iMaxLength, $sMessage)
{
   if (
strlen($sText) > $iMaxLength)
   {
      
$sString = wordwrap($sText, ($iMaxLength-strlen($sMessage)), '[cut]', 1);
      
$asExplodedString = explode('[cut]', $sString);
      
       echo
$sCutText = $asExplodedString[0];
      
      
$sReturn = $sCutText.$sMessage;
   }
   else
   {
      
$sReturn = $sText;
   }
  
   return
$sReturn;
}
?>

Peter (19-Dec-2006 01:00)

The main concern when you have a text in a cell is for long words that drags the cell margins. This function will break words in a text that have more then $nr characters using the "-" char.

<?php
function processtext($text,$nr=10)
    {
       
$mytext=explode(" ",trim($text));
       
$newtext=array();
        foreach(
$mytext as $k=>$txt)
        {
            if (
strlen($txt)>$nr)
            {
               
$txt=wordwrap($txt, $nr, "-", 1);
            }
           
$newtext[]=$txt;
        }
        return
implode(" ",$newtext);
    }
?>

tylernt at gmail dot com (28-Nov-2006 07:39)

I wrote this to keep long strings from making my tables wider than the browser window. To lessen the impact on performance, only call this function on strings longer than 'X' characters.

<?php
// This function will insert the 'wbr' (optional linebreak) tag
// to wrap words in $string longer than 10 characters,
// but will not break inside HTML tags
function mywordwrap($string)
{
$length = strlen($string);

for (
$i=0; $i<=$length; $i=$i+1)
    {
   
$char = substr($string, $i, 1);
    if (
$char == "<")
       
$skip=1;
    elseif (
$char == ">")
       
$skip=0;
    elseif (
$char == " ")
       
$wrap=0;

    if (
$skip==0)
       
$wrap=$wrap+1;

   
$returnvar = $returnvar . $char;

    if (
$wrap>9) // alter this number to set the maximum word length
       
{
       
$returnvar = $returnvar . "<wbr>";
       
$wrap=0;
        }
    }

return
$returnvar;

}
?>

Edward (18-Oct-2006 02:12)

I needed a function to justify the text - not just wrap it. I came up with this:

<?php
function justify($text, $width, $break) {
       
$marker = "__$%@random#$()__";

       
// lines is an array of lines containing the word-wrapped text
       
$wrapped = wordwrap($text, $width, $marker);
       
$lines = explode($marker, $wrapped);
       
       
$result = "";
        foreach (
$lines as $line_index=>$line) {
               
$line = trim($line);
               
               
$words = explode(" ", $line);
               
$words = array_map("trim", $words);
               
$wordcount = count($words);
               
$wordlength = strlen(implode("", $words));
               
                if (
3*$wordlength < 2*$width) {
                       
// don't touch lines shorter than 2/3 * width
                       
continue;
                }
               
               
$spaces = $width - $wordlength;
               
               
$index = 0;
                do {
                       
$words[$index] = $words[$index] . " ";
                       
$index = ($index + 1) % ($wordcount - 1);
                       
$spaces--;
                } while (
$spaces>0);
               
               
$lines[$line_index] = implode("", $words);
        }
       
        return
implode($break, $lines);
}
?>

egyptechno [at] gmail.com (04-Oct-2006 11:12)

Another function to cut text afterr $limit letters ,

function :

<?php
function wordCut($text, $limit, $msg){
    if (
strlen($text) > $limit){
       
$txt1 = wordwrap($text, $limit, '[cut]');
       
$txt2 = explode('[cut]', $txt1);
       
$ourTxt = $txt2[0];
       
$finalTxt = $ourTxt.$msg;
    }else{
       
$finalTxt = $text;
    }
    return
$finalTxt;
}
?>

return :
The limited text

description :
It takes the text, add the string '[cut]' every $limit text by wordwrap, then we explode the text with '[cut]' and takes the first element in the array which we need !

how to use :
wordCut($my_text, 200, '... read more');

EgypTechno

feedback at realitymedias dot com (01-Oct-2006 07:50)

Here is a way to use wordwrap to add spaces to long "words", without breaking link tags -- I came up with this as there apparently is no way to reproduce this effect with a regular expression.

This is mostly used in users-posts where your output layout could be broken with words that are longer than what the container object can take - it will not effect html tags (such as <a href="aaaaaaaaaaaaaaaaaaaaaaaaa"> so you don't end up with broken links !

<?php
$body
= 'this is a text with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa looooooooooooooooooooooooooooong word! <a href="http://www.example.com/with/a/loooooooooooooooooooooong/url'> ... </a>';

foreach(explode(" ", strip_tags($body)) as $key => $line) {
  if (strlen($line) > 35) $body = str_replace($line, wordwrap($line, 25, " ", 1), $body);
}
/*(In case you would like the same thing without the tags protection, there is a regular expression way; */

$body = preg_replace("/([^\s]{35})/","$1 ",$body);
?>

(19-Jul-2006 05:47)

I've written another implemention of textwrap, becourse the last one didnt work for me.

<?php
function textwrap ($text, $length, $break) {
   
$pure=strip_tags($text);
   
$words=str_word_count($pure, 1);
    foreach (
$words as $word) {
        if (
strlen($word) > $length) {
           
$newword=wordwrap($word, $length, $break, TRUE);
           
$text=str_replace($word, $newword, $text);
        }
    }
    return
$text;
}
?>

EngrKhalid (10-Feb-2006 04:54)

I found this function helpful to cut long words without adding spaces:

<?php
function fWrap ( $vText, $vMax ) {
   
$vWords = explode(" ", $vText);
    foreach (
$vWords as $i =>$w ) {
        if (
strlen ( $vWords[$i] ) > $vMax ) { $vWords[$i] = wordwrap( $vWords[$i], $vMax, "<wbr>", 1 ); }
    }
    return
implode(" ", $vWords);
}
?>

Regards.

Dave Lozier - dave at fusionbb.com (30-Nov-2005 08:48)

If you'd like to break long strings of text but avoid breaking html you may find this useful. It seems to be working for me, hope it works for you. Enjoy. :)

<?php
   
function textWrap($text) {
       
$new_text = '';
       
$text_1 = explode('>',$text);
       
$sizeof = sizeof($text_1);
        for (
$i=0; $i<$sizeof; ++$i) {
           
$text_2 = explode('<',$text_1[$i]);
            if (!empty(
$text_2[0])) {
               
$new_text .= preg_replace('#([^\n\r .]{25})#i', '\\1  ', $text_2[0]);
            }
            if (!empty(
$text_2[1])) {
               
$new_text .= '<' . $text_2[1] . '>';   
            }
        }
        return
$new_text;
    }
?>

frans-jan at van-steenbeek dot R-E-M-O-V-E dot net (16-Nov-2005 02:17)

Using wordwrap is usefull for formatting email-messages, but it has a disadvantage: line-breaks are often treated as whitespaces, resulting in odd behaviour including lines wrapped after just one word.

To work around it I use this:

<?php
 
function linewrap($string, $width, $break, $cut) {
 
$array = explode("\n", $string);
 
$string = "";
  foreach(
$array as $key => $val) {
  
$string .= wordwrap($val, $width, $break, $cut);
  
$string .= "\n";
  }
  return
$string;
 }
?>

I then use linewrap() instead of wordwrap()

hope this helps someone

tjomi4 at yeap dot lv (23-Sep-2005 11:26)

utf8_wordwrap();

usage: utf8_wordwrap("text",3,"<br>");
coded by tjomi4`, thanks to SiMM.
web: www.yeap.lv

<?php

function utf8_wordwrap($str,$len,$what){
# usage: utf8_wordwrap("text",3,"<br>");
# by tjomi4`, thanks to SiMM.
# www.yeap.lv
$from=0;
$str_length = preg_match_all('/[\x00-\x7F\xC0-\xFD]/', $str, $var_empty);
$while_what = $str_length / $len;
while(
$i <= round($while_what)){
$string = preg_replace('#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,'.$from.'}'.
                      
'((?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,'.$len.'}).*#s',
                      
'$1',$str);
$total .= $string.$what;
$from = $from+$len;
$i++;
}
return
$total;
}
?>

pawan at shopsbs dot com (14-Aug-2005 06:32)

I wanted to use this function to add a particular text after a certain word count. Here is how I implemented it:

<?php
$content
= wordwrap($content, 200, "....<br /><!--more-->\n");
?>

Above code adds the text '...<br/><!--more-->\n' after a 200 word count. I know there are a million ways this can be done in PHP. Go PHP!

x403 at yandex dot ru (23-Jun-2005 02:35)

String lenght control:

<?php
if (str_word_count($STRING) > 0)
   
$div = strlen($STRING) / str_word_count($STRING);
else return
" ";

if (
$div > 25 ) return wordwrap($STRING, 25, "\n", 1);

return
$STRING;

// Maximum word lenght is 25 chars
?>

Kyle (31-May-2005 07:34)

Yet-another-wordwrap-improvement... If you attempt to wordwrap() lines that already contain some line-breaks that you want to maintain, a simple wrapper around wordwrap can help. For example:

<?php
function preserve_wordwrap($tstr, $len = 75, $br = '\n') {
    
$strs = explode($br,$tstr);
    
$retstr = "";
     foreach (
$strs as $str) {
         
$retstr .= wordwrap($str,$len,$br) . $br;
     }
     return
$retstr;
}
?>

I used a function like this for pulling quotes for my email out of a mysql database and formatting them for use in an email. Some quotes had multiple lines (e.g. a short conversation-style quote) that I wanted to maintain yet still word-wrap correctly.

[EDIT BY danbrown AT php DOT net: Contains a bugfix by (ajd AT cloudiness DOT com) on 13-JUN-05 to address the incorrect order of parameters passed to explode().]

(09-May-2005 06:33)

Note that wordwrap is meant for...wrapping words.  If you're simply trying to break a string into evenly sized pieces, take a look at chunk_split and str_split.

bruceboughton @ google mail (04-May-2005 11:08)

I found that wordwrap deletes the spaces it wraps on. If you want to break up a string which doesn't consist of words, you may find this behaviour undesirable, as I did when trying to wordwrap a Regular Expression to 80 characters (for display along with test string, matches, etc.).

To preserve the spaces and still achieve a consistent cut length, you need to replace spaces with a suitable one-character replacement. I chose the ASCII non-printing character SUB (ASCII #26; some old telephone code meaning substitute):

<?php
$regex
= str_replace(' ', chr(26), $regex);
$regex= wordwrap($regex, 80, '<br />', TRUE);
$regex= str_replace(chr(26), ' ', $regex);
?>

(Of course, you need to replace 80 with your column length and '<br />' with your break string)

grey - greywyvern - com (29-Sep-2004 08:31)

Here's an HTML wrapping + nl2br function I developed.  It inserts line-breaks into long strings of characters in HTML-formatted text while ignoring tags and entities.  It also counts each entity as a single character, and only applies nl2br to text nodes.  You can also tell it to ignore whole elements, like <pre> where adding <br /> isn't necessary. 

Great for formatting HTML generated by user input.  I distribute simple forum and blog scripts where codes input by the user are translated to HTML.  I send the result through this function to format it correctly and make sure they don't maliciously type in long words in order to break my layout.

http://www.greywyvern.com/code/php/htmlwrap_1.0.php.txt

sych at php dot com dot ua (20-Aug-2004 09:25)

wordwrap doesn't know about UTF and considers a multi-byte utf characters as as many characters as there are bytes in there. However, it will still break correctly on " " and "#" (or all other characters in the ascii range (0-127).

However, this is not a bug as it was only meant to work on iso-8859-*.

shaun at phplabs dot com (25-Dec-2002 11:24)

Here's some code which will turn text into a quoted message, that is, split a chunk of text into wrapped lines and prefix each line of text with a > sign (or some other delimiter). I found myself using this snippet so many times while writing an autoresponder that I just dropped it into a function.

<?php
function mailquote($text, $marker){
 
$text = str_replace("\n", "\n$marker", wordwrap($text, 70));
  return
$text;
}
?>

e.g.

mailquote($text, "> ");

> Would result in a long passage of text
> being broken into multiple lines, each
> line starting with a traditional "quote"
> marker, like this.

(25-Aug-2002 08:40)

Instead of using a space or a newline or <br /> as the line break separator, you may consider inserting  "Soft Hyphens" within the middle of long words, allowing elegant word breaking that can use the effective browser layout that is dependant of the effective font that the browser will use.

The "Soft Hyphen" (SHY) character is part of the STANDARD ISO-8859-1 character set: it won't be displayed (i.e. it will have width 0) if the two parts of a word can be displayed by the browser along on the same layout row. However it allows the browser to find a break in the middle of long words: in that case, it will display the first part of the word before the "Soft Hyphen", and a true Hyphen ("-") on the first layout row (if they both fit on that row), and the next part after the "Soft Hyphen" on the following layout row.

Ideally, each word should contain at least one "Soft Hyphen" between each syllable of a word, unless this would place a "Soft Hyphen" with less than 3 characters from the beginning or end of the word. So "Soft Hyphens" must not be inserted within words with 1 to 5 characters.

The Soft Hyphen is only appropriate within textual words using Latin, Greek, Cyrillic characters). For Semitic languages that use right to left scripts, the "Soft Hyphen" should be replaced by a "Soft Line Break" (also called "Zero Width Non Joiner" in Unicode).

This "Soft Line Break" always has a null display width (i.e. it is never displayed), except that it allows inserting a line break.

Some characters are already implicitly considered followed by a "Soft Line Break" in browsers: the explicit hyphen within composed words (like "week-end"), and all punctuations (with the exception of the dot, and opening punctuations like "({[" which are instead _preceded_ by an implicit "Soft Line Break").

Note also that some new browsers can insert themselves "Soft Hyphens" or "Soft Line Breaks" within long words, if the HTML page explicitly specifies the language, and the words are restricted to the natural characters of that language, using hyphenation rules and/or dictionnaries defined for that language.

Currently, the HTML standard offers no way to specify a set of hyphenation rules along with the page (so that it would work in absence of a known dictionnary for that language), so soft hyphens or line breaks should be placed in the content.

warwallace at [nospam]wargardens dot com (22-Jul-2002 05:44)

It is also possible to consider this function as a tool for making text wrappable rather than simply for forcing wrapping.

In other words, use a space as the break - rather than "br /" or "p" or \n or whatever - and the text becomes wrappable.

<?php
$input
= "I want to annoy you by inserting long wooooooooooooooooooooooooooooooooorrrrrrdddss into your guestbook.";
$output = wordwrap($input, 40, ' ', 1);
?>

Will insert spaces into the words longer than 40 characters make the text wrappable by the browser.

toxic79_spam at yahoo dot com (12-Jul-2002 04:02)

I've noticed that if you have a string of, say, 8 characters and you set it to wrap at 8 characters with a break tag it will add the break tag after the 8th character even if the string is only 8 characters long. this was frustrating because I only wanted the break tag if there would be more text after it. it would be cool to have a flag that would stop this from happening, or a flag that would put the break tag (or whatever you use) before the number you break on, so you could set it to break every 9th character and it would only insert the tag after the 8th if there are more than 8 characters.

until then, however, here is my lame fix. $str is the string to wrap, $num is the number of characters to wrap after and $break is the text to use to wrap the string.

<?php
function my_wordwrap( $str, $num, $break )
{
   
// get the wordwrapped string
   
$tmp_str = wordwrap( trim( $str ), $num, $break, 1 );

   
// get the string length of the breaking tag
   
$strlen_break = strlen( $break );

   
// if the last $strlen_break characters of the wordwrapped string is $break ...
   
if ( substr( $tmp_str, ( 0 - $strlen_break )) == $break )
    {
       
// strip the last $strlen_break characters off the end
       
$tmp_str = substr( $tmp_str, 0, count( $tmp_str ) - $strlen_break - 1 );
    }
       
   
// return the results
   
return $tmp_str;
}
?>

ekgerke at yahoo dot com (11-Mar-2002 06:39)

If the last line of string does not end with newline character, wordwrap tends to add trailing garbage.

timf at tfountain dot co dot uk (01-Jan-2002 11:18)

If you're having problems with a small fixed width table/table cell being stretched by people typing entering long text (such as a URL or an email address), then one (MSIE only, unfortunately) solution is to use style="table-layout:fixed" in the <table> tag.  This will break any words that would normally expand your table and mess up your layout.

wordwrap() can't help in this situation because you want to wrap if the text is wider than X pixels, rather than X characters, which of course PHP has know way of knowing.