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);
}
?>
wordwrap
(PHP 4 >= 4.0.2, PHP 5)
wordwrap — Wraps a string to a given number of characters
Description
Wraps a string to a given number of characters using a string break character.
Parameters
- str
-
The input string.
- width
-
The column width. Defaults to 75.
- break
-
The line is broken using the optional break parameter. Defaults to '\n'.
- cut
-
If the cut is set to TRUE, the string is always wrapped at the specified width. So if you have a word that is larger than the given width, it is broken apart. (See second example).
Return Values
Returns the given string wrapped at the specified column.
ChangeLog
| Version | Description |
|---|---|
| 4.0.3 | The optional cut parameter was added. |
Examples
Example #1 wordwrap() example
<?php
$text = "The quick brown fox jumped over the lazy dog.";
$newtext = wordwrap($text, 20, "<br />\n");
echo $newtext;
?>
The above example will output:
The quick brown fox<br /> jumped over the lazy<br /> dog.
Example #2 wordwrap() example
<?php
$text = "A very long woooooooooooord.";
$newtext = wordwrap($text, 8, "\n", true);
echo "$newtext\n";
?>
The above example will output:
A very long wooooooo ooooord.
wordwrap
31-Aug-2008 03:21
28-May-2008 01: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)
25-Apr-2008 10: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;
}
?>
21-Apr-2008 02:40
This function can be useful for wrap string by specify chars, not only space char.
<?php
/**
* Wrap string by specify chars
*
* @param string $strForWrap
* @param integer $maxLength
* @param string $breakChar
* @param array $wrapChars
*
* @author Ivan Chura
* @since 21.04.2008
* @return string
**/
function wordwrapBySpecifyChars($strForWrap, $maxLength = 80, $breakChar = "\n", $wrapChars = array(",", ";" ))
{
$newStr = null;
$length_of_string = strlen($strForWrap);
if ($length_of_string <= $maxLength)
{
return $strForWrap;
}
$count_of_string = 1;
$wait_new_line = false;
for($i=0; $i<$length_of_string; $i++)
{
if ( $count_of_string*$maxLength == $i || $wait_new_line)
{
if (in_array($strForWrap{$i}, $wrapChars ) )
{
$count_of_string ++;
$newStr .= $strForWrap{$i}.$breakChar;
$wait_new_line = false;
}
else
{
$newStr .= $strForWrap{$i};
$wait_new_line = true;
}
}
else
{
$newStr .= $strForWrap{$i};
}
}
return $newStr;
}
?>
17-Apr-2008 10: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 :)
}
?>
16-Apr-2008 11: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
09-Apr-2008 11:05
@znupiDONTWANTSPAM69 at gmail dot comBLAH
the layout_wrap function doesn't work as I expected. Following is my version. It may consume more resource but gives solid result:
<?php
function longword_break($str, $i) {
if ((empty($str))||(strlen($str)<$i)){
return $str;
}
$words_arr = explode(' ', $str);
foreach ($words_arr as &$word){
$br_word = explode("\n", $word);
//Process some run-in words conected by "\n"
foreach ($br_word as &$r_word){
$j=$i;
while($j < strlen($r_word)) {
$r_word = substr($r_word, 0, $j) . ' '. substr($r_word, $j);
$j+= ($i +1);
}
}
$word =implode("\n", $br_word);
unset($r_word);
}
unset($word);
$str = implode(' ',$words_arr);
//return nl2br(wordwrap($str, $i,"\n", true));
//return nl2br($str);
return $str;
}
// Some test:
$str = "This is 0123456789
aaaaaa ttttttttttttttttttttt
ccc gggggggggg";
$str1 = "aaaaaaaaaaatessssssssssssssssstxxx";
echo "Orgininal string:<br />" . $str . "<br />";
echo "Layout wrap function: <br />" . layout_wrap($str,5). "<br />";
echo "Long word break function: <br/>" . longword_break($str,5). "<br />";
?>
Output:
Orgininal string:
This is 0123456789 aaaaaa ttttttttttttttttttttt ccc gggggggggg
Layout wrap function:
This is 0123456 789 aaaaaa ttttttt tttt tttt tttt tt ccc ggggggg ggg
<!--Notice some "words" are still longer than 5 characters. /-->
Long word break function:
This is 01234 56789 aaaaa a ttttt ttttt ttttt ttttt t ccc ggggg ggggg
04-Apr-2008 06:15
When using wordwrap() on a long word (an English word), It's best to use "-\n" as the '$string break' argument. Why? Because when you're forcing a cut (as bool TRUE), proper English is to include the hyphen to let the reader know that a certain word is being continued on the next line. A good example would be like: http://www.codehelpers.com/Worlds%20Longest%20English%20Word.php
<?php
echo wordwrap($word, 100, "-\n", true);
?>
24-Feb-2008 05:05
If you are dealing with strings that may be very long and without spaces, but at the same time may be very long WITH spaces and you don't want the ones without spaces ruining your HTML+CSS layout, here's a function that adds a space (" ") after every $i characters, if no space is found until that character, so the browser will automatically wrap the text:
<?php
function layout_wrap($str, $i) {
$j = $i;
while ($i < strlen($str)) {
if (strpos($str, ' ', $i-$j+1) > $i+$j || strpos($str, ' ', $i-$j+1) === false) {
$str = substr($str, 0, $i) . ' ' . substr($str, $i);
}
$i += $j;
}
return $str;
}
?>
Hope this helps someone :-)
19-Feb-2008 09: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)
27-Jan-2008 02:35
This function will provide word-wrap functionality to Firefox (most other browsers have a CSS alternative) by using a zero-width character between every character of any word that goes past the limited size.
<?php
/**
* @desc Wraps a string using a zero-width character between each character of any word past the size limit.
* @param string String to wrap
* @param int Word length limit
*
* @return string Cut string
*/
function cut_word($txt, $where=12) {
if (empty($txt)) return false;
for ($c = 0, $a = 0, $g = 0; $c<strlen($txt); $c++) {
$d[$c+$g]=$txt[$c];
if ($txt[$c]!=" ") $a++;
else if ($txt[$c]==" ") $a = 0;
if ($a>$where) {
$g++;
$d[$c+$g]="​";
}
}
return implode("", $d);
}
?>
15-Jan-2008 12:42
<?php
#for those who don't like word-wrap
function ($string, $max_length) {
$a_string = explode(" ",$string);
foreach ($a_string as $value)
{
if (strlen($value) > $max_length)
{
$length = strlen($value);
$repeats = $length / $max_length;
for ($i=0; $i<$repeats; $i++)
{
$str = substr ($value,($i*$max_length),$max_length);
print "<font color=red>".$str."</font><br />";
}
} else {
print $value."<br />";
}
}
}
?>
30-Oct-2007 10:33
<?php
function strwidth($s){
/*
put some fix for ambiguous width hese
*/
$ret = mb_strwidth($s, 'UTF-8');
return $ret;
}
function mb_wordwrap($str, $wid, $tag){
$pos = 0;
$tok = array();
$l = mb_strlen($str, 'UTF-8');
if($l == 0){
return '';
}
$flag = false;
$tok[0] = mb_substr($str, 0, 1, 'UTF-8');
for($i = 1 ; $i < $l ; ++$i){
$c = mb_substr($str, $i, 1, 'UTF-8');
if(!preg_match('/[a-z\'\"]/i',$c)){
++$pos;
$flag = true;
}elseif($flag){
++$pos;
$flag = false;
}
$tok[$pos] .= $c;
}
$linewidth = 0;
$pos = 0;
$ret = array();
$l = count($tok);
for($i = 0 ; $i < $l ; ++$i){
if($linewidth + ($w = strwidth($tok[$i])) > $wid){
++$pos;
$linewidth = 0;
}
$ret[$pos] .= $tok[$i];
$linewidth += $w;
}
return implode($tag, $ret);
}
?>
25-Oct-2007 07:12
Disregard my note from below, since the function only works for utf8 strings that can be encoded into ISO-8859-1.
25-Oct-2007 05:36
Wordwrap for utf8. Easy to understand and works with the $cut parameter:
<?php
function utf8_wordwrap($str,$width=75,$break="\n", $cut=false){
return utf8_encode(wordwrap(utf8_decode($str), $width, $break, $cut));
}
?>
08-Oct-2007 07: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;
}
?>
24-Sep-2007 05:52
luismorrison's function will split a string into a first and second line *only*. If your string is 100 characters long and you wrap at 30 characters you will end up with 30 chars on line 1 and 70 on line 2.
I've included an English translation here for reference as I was going round the bend trying to figure it out in Spanish! :)
<?php
function splitstroverflow($chain,$length) {
$pri_line = array();
$seg_line = array();
$words = explode(" ",trim($chain));
for ($i = 0; $i < count($words); $i++) {
$sum += strlen($words[$i])+1;
if ($sum >= $length) $seg_line[] = $words[$i] . " ";
else $pri_line[] = $words[$i] . " ";
}
for ($i = 0; $i < count($pri_line); $i++)
$lines[0] .= $pri_line[$i];
for ($i = 0; $i < count($seg_line); $i++)
$lines[1] .= $seg_line[$i];
return $lines;
}
?>
16-Aug-2007 07:21
i wrote this by mistake because i didn't know that the same function already exists in PHP.. well shit happens, its quite simple but maybe this will help you someday in your project. The difference is that the one i wrote, called 'splitstroverflow()', cuts given string and parses into arrays to do whatever you like with them.
<?php
function splitstroverflow($cadena,$longitud) {
$pri_renglon = array();
$seg_renglon = array();
$palabras = explode(" ",trim($cadena));
for ($i = 0; $i < count($palabras); $i++) {
$sum += strlen($palabras[$i])+1;
if ($sum >= $longitud) $seg_renglon[] = $palabras[$i] . " ";
else $pri_renglon[] = $palabras[$i] . " ";
}
for ($i = 0; $i < count($pri_renglon); $i++)
$renglones[0] .= $pri_renglon[$i];
for ($i = 0; $i < count($seg_renglon); $i++)
$renglones[1] .= $seg_renglon[$i];
return $renglones;
}
?>
Usage:
<?php
splitstroverflow(str longString,int lenght);
$myrow = splitstroverflow("This is my long long long string",18);
// the array counts 2 elements
// Array
// (
// [0] => "This is my long"
// [1] => "long long string"
// )
?>
29-Jun-2007 11: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éfé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;
}
?>
16-May-2007 06: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;
}
?>
27-Mar-2007 04: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;
}
?>
19-Dec-2006 02: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);
}
?>
