Alessandro Alessandro - 3 months ago 9
HTML Question

PHP 7: custom wordwrap function preserving html written in php produces warning

Usually I use a custom wordwrap function that takes more care with html tag avoiding to split them and preserving the html structure... recently when I was testing my apps under php 7.0.9 I noted a strange warning and so I tried to reproduce it. In other ways the function works fine but if finds some combinations of html/words wakes up with a warning...

<?php
### This function break long strings without broke html tag
function html_wordwrap($str, $cols, $cut) {
$tag_open = '<';
$tag_close = '>';
$count = 0;
$in_tag = 0;
$str_len = strlen($str);
$segment_width = 0;
for ($i = 1; $i <= $str_len; $i++) {
if ((isset($str[$i])) && ($str[$i] == $tag_open)) {
$in_tag++;
} elseif ((isset($str[$i])) && ($str[$i] == $tag_close)) {
if ($in_tag > 0) {
$in_tag--;
}
} else {
if ($in_tag == 0) {
$segment_width++;
if (($segment_width > $cols) && ($str[$i] == " ")) {
$str = substr($str,0,$i).$cut.substr($str,$i+1,$str_len-1);
$i += strlen($cut);
$str_len = strlen($str);
$segment_width = 0;
}
}
}
}
return $str;
}
?>


Applying to my string produces a warning

<?php
### This function break long strings without broke html tag
function html_wordwrap($str, $cols, $cut) {
$tag_open = '<';
$tag_close = '>';
$count = 0;
$in_tag = 0;
$str_len = strlen($str);
$segment_width = 0;
for ($i = 1; $i <= $str_len; $i++) {
if ((isset($str[$i])) && ($str[$i] == $tag_open)) {
$in_tag++;
} elseif ((isset($str[$i])) && ($str[$i] == $tag_close)) {
if ($in_tag > 0) {
$in_tag--;
}
} else {
if ($in_tag == 0) {
$segment_width++;
if (($segment_width > $cols) && ($str[$i] == " ")) {
$str = substr($str,0,$i).$cut.substr($str,$i+1,$str_len-1);
$i += strlen($cut);
$str_len = strlen($str);
$segment_width = 0;
}
}
}
}
return $str;
}
$body = "Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... <img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\">Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede...";
echo html_wordwrap($body, 300, "\r\n ");
?>


Now you can test by yourself and see that produces a warning like this:

Notice: Uninitialized string offset: 4398 in D:\Web\test\index.php on line 19

if (($segment_width > $cols) && ($str[$i] == " ")) {


Someone ha some ideas? I suspect that the cycle for is wrong... Thanks.

Answer
<?php
  function html_wordwrap($str, $cols, $cut) {
    $tag_open = '<';
    $tag_close = '>';
    $in_tag = 0;
    $str_len = strlen($str);
    $cl = strlen($cut);
    $segment_width = 0;
    for ($i = 0; $i < $str_len; $i++) {
      $c = substr($str, $i, 1);
      if ($c === $tag_open) {
        $in_tag++;
      } elseif ($c === $tag_close) {
        if ($in_tag > 0) {
          $in_tag--;
        }
      } else {
        if ($in_tag == 0) {
          $segment_width++;
          if ($segment_width > $cols && $c === ' ') {
            $str = substr($str, 0, $i) . $cut . substr($str, $i + 1);
            $i += $cl;
            $str_len += $cl; //strlen($str);
            $segment_width = 0;
          }
        }
      }
    }
    return $str;
  }
  $body = "Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... <img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\"><img src=\"http://www.alecos.it/gfx/Logo.png\" title=\"Questo è il logo di Alecos\" alt=\"Immagine\">Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede... Ecco vediamo che succede...";
  echo html_wordwrap($body, 300, "\r\n    ");
?>

This solution was found thanks to my friend Cristiano that improved my function. Here is for everyone that is looking for that solution...