substr question

$post_content1 = substr($r["post_content"], 0, 85);

I am using this code to trim text stored in a variable to 85 characters. The problem is that sometimes it cuts off the middle of a word. Is there a way to stop it before it cuts off the word?

lvollmerAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
secondvConnect With a Mentor Commented:
My bad. I think I may need sleep ;)  That should have been:

<?php

function max_len($string, $limit = 85)
{
      $words = preg_split('# #', $string, -1, PREG_SPLIT_NO_EMPTY);
      $newstring = '';

      for ($i = 0; strlen("$newstring{$words[$i]} ") <= $limit; $i++)
      {
            $newstring .= "{$words[$i]} ";
      }
      return rtrim($newstring);
}

if ($r = mysql_fetch_array($result))
{
      $domain1 = $r['domain'];
      $post_title1 = $r['post_title'];
      $post_content1 = max_len($r['post_content'], 55);
      //$blog_id1 = $r['blog_id'];
      $button1 = $r['button'];
      $summary1 = $r['summary'];
}

if ($r = mysql_fetch_array($result))
{
      $domain2 = $r['domain'];
      $post_title2 = $r['post_title'];
      $post_content2 = addslashes(max_len($r['post_content'], 55));
      //$blog_id2 = $r['blog_id'];
      $button2 = $r['button'];
      $summary2 = $r['summary'];
}

if ($r = mysql_fetch_array($result))
{
      $domain3 = $r['domain'];
      $post_title3 = $r['post_title'];
      $post_content3 = addslashes(max_len($r['post_content'], 55));
      //$blog_id3 = $r['blog_id'];
      $button3 = $r['button'];
      $summary3 = $r['summary'];
}

if ($r = mysql_fetch_array($result))
{
      $domain4 = $r['domain'];
      $post_title4 = $r['post_title'];
      $post_content4 = addslashes(max_len($r['post_content'], 55));
      //$blog_id4 = $r['blog_id'];
      $button4 = $r['button'];
      $summary4 = $r['summary'];
}

?>
0
 
b0lsc0ttIT ManagerCommented:
Is 85 the very max or can it go to the next space?  I will assume you can go on.

Use ...

var limit = 85;
if (string.indexOf(' ', limit) != -1) limit = string.indexOf(' ', limit);
string = string.substring(0, limit);

Let me know how that works or if you have a question.

bol
0
 
rdivilbissCommented:
$tmp = split(" ",$r["post_content"];
 $post_content1 = "";

for ($idx=0;$idx<count($tmp);$idx++) {
      if (strlen($post_content1 . " " . $tmp[idx])<85) {
           $post_content1 .= " ". $tmp[idx]]
      }
}
0
The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

 
b0lsc0ttIT ManagerCommented:
Sorry, that code was for Javascript.  The idea still holds.  Let me work on some PHP for you.

bol
0
 
lvollmerAuthor Commented:
85 is the max - let me try these solutions
0
 
lvollmerAuthor Commented:
thanks bolscott
0
 
TeRReFCommented:
How about something like:

function trimLength($s, $maxlength = 50) {
        $words = explode(' ', $s);
        $split = '';
        foreach ($words as $word) {
                if (strlen($split) + $word < $maxlength)
                        $split .= $word.' ';
                else
                        break;
        }
        return trim($split);
}
0
 
rdivilbissConnect With a Mentor Commented:
This is more efficient than my previous code and nearly identical to bol..typing while you were posting.

<?PHP
$string1 = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras dolor. Sed sed neque. Duis eros justo, bibendum in, placerat eget, ullamcorper vel, nibh. Praesent urna arcu, sagittis eget, semper laoreet, tempus non, augue. In a pede. Vestibulum consequat eleifend sem. Duis tristique tortor ultricies massa. Duis sapien eros, posuere sit amet, rhoncus non, venenatis bibendum, tellus. Donec dui tortor, dignissim quis, eleifend eget, fermentum a, massa. Maecenas vel enim vitae sapien condimentum eleifend. Duis hendrerit luctus dui. Donec sem dui, posuere a, consectetuer eget, pretium aliquet, turpis. Vestibulum posuere porta lacus. Sed convallis molestie purus. In hac habitasse platea dictumst.";
$string2 = "Mauris aliquam orci vel enim aliquam venenatis. Aenean nec nisl. Phasellus tincidunt. Quisque diam. Donec cursus convallis sapien. Sed at libero sed nulla euismod accumsan. Sed eget turpis eu purus aliquam facilisis. Curabitur vestibulum, massa eu sodales pulvinar, purus urna mollis augue, ac consequat nisi augue eget magna. Nunc aliquet urna id felis. Etiam magna arcu, lobortis ut, feugiat et, hendrerit a, tortor. Duis porttitor vestibulum nisi. In quis dolor non pede tempus tempus. Donec et libero. Sed non est non sapien aliquet interdum.";
$string3 = "Donec urna magna, rhoncus venenatis, consectetuer ut, imperdiet ac, nulla. Quisque commodo. Cras sed enim. Proin diam urna, venenatis nec, porttitor at, tincidunt sed, felis. Cras dictum dolor nec justo. Pellentesque at odio vel metus tempus nonummy. Fusce cursus nulla sed eros. Cras in purus. Nulla sit amet libero. Morbi convallis, orci vel consectetuer vehicula, velit ligula accumsan lorem, sit amet tincidunt quam turpis vel urna. Cras nulla neque, mattis fermentum, molestie vel, mollis non, lacus. Donec commodo justo in quam. Nullam sodales nisi et magna. Phasellus ut lectus quis pede iaculis pellentesque. Fusce in massa. Proin fermentum ligula eget mauris.";

function max85($pStr) {
      $tmp = split(" ",$pStr);
      $out = "";
      $idx=0;
      while (strlen($out . " " . $tmp[$idx])<85) {
            $out .= " " . $tmp[$idx];
            $idx += 1;
      }
      return $out;
}

echo $string1 . "<br><br>";
echo max85($string1) . "<br><br>";
echo $string2 . "<br><br>";
echo max85($string2) . "<br><br>";
echo $string3 . "<br><br>";
echo max85($string3) . "<br><br>";
?>
0
 
rdivilbissCommented:
TeRReF, did you forget to put the spaces back between the words?
0
 
TeRReFCommented:
No?! Look at this line:
$split .= $word.' ';
0
 
rdivilbissCommented:
Oh, I see the space it at the end, never mind.
0
 
TeRReFCommented:
Btw. your code will leave the chopped string with an extra space at the beginning if I'm not mistaken? You'll need a trim in the return line as well :)
0
 
b0lsc0ttConnect With a Mentor IT ManagerCommented:
My steps in PHP would be ...

$limit = 85;
if (!strpos($string, ' ', $limit) === false) {
    $limit = strpos($string, ' ', $limit);
}
$string = substr($string, 0, $limit);

However I don't know if this would be better than using an array (the method suggested by Terref or Rdivilbiss.  In fact, in some cases I have seen problems using strpos so that may be why they avoid it.  I am interested in opinions on it, especially if there would be an issue with PHP because I would usually prefer something like this to an array method.

bol
0
 
rdivilbissCommented:
bol & tref you're running over:

http://www.cafesong.com/test/max85.php

<?PHP
$string1 = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras dolor. Sed sed neque. Duis eros justo, bibendum in, placerat eget, ullamcorper vel, nibh. Praesent urna arcu, sagittis eget, semper laoreet, tempus non, augue. In a pede. Vestibulum consequat eleifend sem. Duis tristique tortor ultricies massa. Duis sapien eros, posuere sit amet, rhoncus non, venenatis bibendum, tellus. Donec dui tortor, dignissim quis, eleifend eget, fermentum a, massa. Maecenas vel enim vitae sapien condimentum eleifend. Duis hendrerit luctus dui. Donec sem dui, posuere a, consectetuer eget, pretium aliquet, turpis. Vestibulum posuere porta lacus. Sed convallis molestie purus. In hac habitasse platea dictumst.";
$string2 = "Mauris aliquam orci vel enim aliquam venenatis. Aenean nec nisl. Phasellus tincidunt. Quisque diam. Donec cursus convallis sapien. Sed at libero sed nulla euismod accumsan. Sed eget turpis eu purus aliquam facilisis. Curabitur vestibulum, massa eu sodales pulvinar, purus urna mollis augue, ac consequat nisi augue eget magna. Nunc aliquet urna id felis. Etiam magna arcu, lobortis ut, feugiat et, hendrerit a, tortor. Duis porttitor vestibulum nisi. In quis dolor non pede tempus tempus. Donec et libero. Sed non est non sapien aliquet interdum.";
$string3 = "Donec urna magna, rhoncus venenatis, consectetuer ut, imperdiet ac, nulla. Quisque commodo. Cras sed enim. Proin diam urna, venenatis nec, porttitor at, tincidunt sed, felis. Cras dictum dolor nec justo. Pellentesque at odio vel metus tempus nonummy. Fusce cursus nulla sed eros. Cras in purus. Nulla sit amet libero. Morbi convallis, orci vel consectetuer vehicula, velit ligula accumsan lorem, sit amet tincidunt quam turpis vel urna. Cras nulla neque, mattis fermentum, molestie vel, mollis non, lacus. Donec commodo justo in quam. Nullam sodales nisi et magna. Phasellus ut lectus quis pede iaculis pellentesque. Fusce in massa. Proin fermentum ligula eget mauris.";

function max85($pStr) {
      $tmp = split(" ",$pStr);
      $out = "";
      $idx=0;
      while (strlen($out . $tmp[$idx]. " " )<85) {
            $out .= $tmp[$idx]. " " ;
            $idx += 1;
      }
      return trim($out);
}

function bols($pStr){
      $limit = 85;
      if (!strpos($pStr, ' ', $limit) === false) {
          $limit = strpos($pStr, ' ', $limit);
      }
      return substr($pStr, 0, $limit);
}


function tref($s, $maxlength = 85) {
        $words = explode(' ', $s);
        $split = '';
        foreach ($words as $word) {
                if (strlen($split) + $word < $maxlength)
                        $split .= $word.' ';
                else
                        break;
        }
        return trim($split);
}


echo $string1 . "<br><br>";
echo "<b>rod</b> " .max85($string1) . " Len: " . strlen(max85($string1)) ."<br><br>";
echo "<b>bol</b> " .bols($string1) . " Len: " . strlen(bols($string1)) . "<br><br>";
echo "<b>tref</b> " .tref($string1) . " Len: " . strlen(tref($string1)) . "<br><br>";
echo $string2 . "<br><br>";
echo "<b>rod</b> " .max85($string2) . " Len: " . strlen(max85($string2)). "<br><br>";
echo "<b>bol</b> " .bols($string2) . " Len: " . strlen(bols($string2)). "<br><br>";
echo "<b>tref</b> " .tref($string2) . " Len: " . strlen(tref($string2)) . "<br><br>";
echo $string3 . "<br><br>";
echo "<b>rod</b> " .max85($string3) . " Len: " . strlen(max85($string3)). "<br><br>";
echo "<b>bol</b> " .bols($string3) . " Len: " . strlen(bols($string3)). "<br><br>";
echo "<b>tref</b> " .tref($string3) . " Len: " . strlen(tref($string3)) . "<br><br>";
?>
0
 
rdivilbissCommented:
@TeRReF, you're right...I should have put the space at the end as you did, as reflected above.

It's interesting to see three programmers take three different approaches.  Want me to up the string counts and run timers, LOL.
0
 
TeRReFCommented:
b0lsc0tt's method is the fastest one and the most efficient when it comes to resources.

I stopped using strpos() for this sort of stuff a long time ago, but I can't remember why anymore. Multibyte chars seem to ring a bell. Although I read on php.net that the function is binary safe (now).
0
 
b0lsc0ttConnect With a Mentor IT ManagerCommented:
Yes, it would.  I misread the reply that said 85 was the max.  My code would do 85 or to the next space after 85.  Keeping with that idea (strpos) I would then use ...

$limit = 85;
$string = substr($string, 0, $limit);
if (!strrpos($string, ' ') === false) {
    $limit = strpos($string, ' ');
}
$string = substr($string, 0, $limit);

It would trim the string to the max allowed, look for the last space, and then trim again.

bol
0
 
b0lsc0ttIT ManagerCommented:
Oops typo.  I did need to change to strrpos for this and forgot to change the second strpos.

$limit = 85;
$string = substr($string, 0, $limit);
if (!strrpos($string, ' ') === false) {
    $limit = strrpos($string, ' ');
}
$string = substr($string, 0, $limit);
0
 
rdivilbissCommented:
Updated.  Seems I'm running under on the first string.
0
 
rdivilbissCommented:
http://www.cafesong.com/test/max85-1.php

b0lsc0tt's method is consistently faster.

Boo!!! LOL

0
 
raja_ind82Commented:
<?php
$teststring="rajaaa string example.";
$count=15;
$trimtext= Substr($teststring,0,$count);
$lastchr= substr($trimtext, -1);
while ($lastchr!=' ' && $count< strlen($teststring))
{
      $count=$count+1;
      $trimtext= Substr($teststring,0,$count);
      $lastchr= substr($trimtext, -1);
}
echo "Original String: <b>".$teststring."</b><br>";
echo "Trimed String: <b>".$trimtext."</b><br>";
echo "String Length: ".$count;
?>

Regards,
M.Raja
0
 
secondvCommented:
Figured I'd add something too, lol.

<?php

$string = 'My string blah blah um blah and um blah again? Yes possibly.';

function max_len($string, $limit = 85)
{
      $words = preg_split('# #', $string, -1, PREG_SPLIT_NO_EMPTY);
      $newstring = '';

      for ($i = 0; strlen("$newstring{$words[$i]} ") <= $limit; $i++)
      {
            $newstring .= "{$words[$i]} ";
      }
      return rtrim($newstring);
}

echo max_len($string, 40);

?>
0
 
secondvCommented:
And don't mind the  '40', was just some testing I was doing ;)
0
 
lvollmerAuthor Commented:
so if this is my array

if( $r=mysql_fetch_array( $result ) )
    $domain1 = $r[ "domain" ];
      $post_title1 = $r[ "post_title" ];
      $post_content1 = substr($r["post_content"], 0, 55);
      //$blog_id1 = $r[ "blog_id" ];
      $button1 = $r[ "button" ];
      $summary1 = $r[ "summary" ];
if( $r=mysql_fetch_array( $result ) )
    $domain2 = $r[ "domain" ];
      $post_title2 = $r[ "post_title" ];
      $post_content2 = addslashes(substr($r["post_content"], 0, 55));
      //$blog_id2 = $r[ "blog_id" ];
      $button2 = $r[ "button" ];
      $summary2 = $r[ "summary" ];
if( $r=mysql_fetch_array( $result ) )
    $domain3 = $r[ "domain" ];
      $post_title3 = $r[ "post_title" ];
      $post_content3 = addslashes(substr($r["post_content"], 0, 55));
      //$blog_id3 = $r[ "blog_id" ];
      $button3 = $r[ "button" ];
      $summary3 = $r[ "summary" ];
if( $r=mysql_fetch_array( $result ) )
    $domain4 = $r[ "domain" ];
      $post_title4 = $r[ "post_title" ];
      $post_content4 = addslashes(substr($r["post_content"], 0, 55));
      //$blog_id4 = $r[ "blog_id" ];
      $button4 = $r[ "button" ];
      $summary4 = $r[ "summary" ];



How do I apply that logic to post_content
0
 
secondvCommented:
<?php

function max_len($string, $limit = 85)
{
      $words = preg_split('# #', $string, -1, PREG_SPLIT_NO_EMPTY);
      $newstring = '';

      for ($i = 0; strlen("$newstring{$words[$i]} ") <= $limit; $i++)
      {
            $newstring .= "{$words[$i]} ";
      }
      return rtrim($newstring);
}

if ($r = mysql_fetch_array($result))
{
      $domain1 = $r['domain'];
      $post_title1 = $r['post_title'];
      $post_content1 = max_len($r['post_content'], 55);
      //$blog_id1 = $r['blog_id'];
      $button1 = $r['button'];
      $summary1 = $r['summary'];
}

if ($r = mysql_fetch_array($result))
{
      $domain1 = $r['domain'];
      $post_title1 = $r['post_title'];
      $post_content1 = addslashes(max_len($r['post_content'], 55));
      //$blog_id1 = $r['blog_id'];
      $button1 = $r['button'];
      $summary1 = $r['summary'];
}

if ($r = mysql_fetch_array($result))
{
      $domain1 = $r['domain'];
      $post_title1 = $r['post_title'];
      $post_content1 = addslashes(max_len($r['post_content'], 55));
      //$blog_id1 = $r['blog_id'];
      $button1 = $r['button'];
      $summary1 = $r['summary'];
}

if ($r = mysql_fetch_array($result))
{
      $domain1 = $r['domain'];
      $post_title1 = $r['post_title'];
      $post_content1 = addslashes(max_len($r['post_content'], 55));
      //$blog_id1 = $r['blog_id'];
      $button1 = $r['button'];
      $summary1 = $r['summary'];
}

?>
0
 
b0lsc0ttIT ManagerCommented:
>> How do I apply that logic to post_content <<

Put the code you want to use in a function and call it when you set post_content or on the next line to change its value.  The code above shows an example but may have a problem.  In that code max_len is the function but then addslashes() is called.  Is it OK for the length to change from that function and be longer?  If not, the function you use to "trim" (e.g. max_len) should be called last.

If you want to use my code in a function then put this block above the array code and then call it using trim85().

function trim85($string) {
    $limit = 85;
    $string = substr($string, 0, $limit);
    if (!strrpos($string, ' ') === false) {
        $limit = strrpos($string, ' ');
    }
    $string = substr($string, 0, $limit);
}

Let me know how this helps or if you have a question.

bol
0
 
lvollmerAuthor Commented:
seems to be working now. let me run a few more tests
0
 
b0lsc0ttIT ManagerCommented:
I'm glad I could help you.  Thanks for the grade, the points and the fun question.

bol
0
 
lvollmerAuthor Commented:
no prob - hope i hit all the participants with points
0
 
rdivilbissCommented:
Well thanks for your generosity...bols had the best answer, but it was fun to compare all the different methods.

Kudo's to bol!

I will no proceed to swipe his code, LOL.
0
 
b0lsc0ttIT ManagerCommented:
@Rdivilbiss - LOL. Thanks!  I'm glad it helped more than just Lvollmer.  I sometimes get as much as the questioner from a question because of other expert's comments.  A great site and, Lvollmer, thanks again for a fun question!  :D

bol
0
 
lvollmerAuthor Commented:
i need to take this one step further - ill post the links shortly
0
 
lvollmerAuthor Commented:
0
 
b0lsc0ttIT ManagerCommented:
This is a better link.

http:Q_22483409.html

bol
0
 
lvollmerAuthor Commented:
thanks
0
 
b0lsc0ttIT ManagerCommented:
Your welcome!  The page you linked to was just the confirmation page.  In the future you just need to click on the button to view the question and then copy that URL.  I posted a shorter version of that URL but that is how I got it.

bol
0
 
lvollmerAuthor Commented:
thanks again
0
All Courses

From novice to tech pro — start learning today.