Substr di PHP ma mantenere i tag HTML?

Mi chiedo se c'è un modo elegante per tagliare un po 'di text, ma mentre si è in grado di riconoscere i tag HTML?

Ad esempio, ho questa string:

$data = '<strong>some title text here that could get very long</strong>'; 

Diciamo che ho bisogno di restituire / emettere questa string su una pagina ma vorrei che non fosse più di X caratteri. Diciamo 35 per questo esempio.

Quindi io uso:

 $output = substr($data,0,20); 

Ma ora finisco con:

 <strong>some title text here that 

che come puoi vedere i forti tag di chiusura vengono scartati rompendo così la visualizzazione HTML.

C'è un modo per aggirare questo? Si noti inoltre che è ansible avere più tag nella string, ad esempio:

 <p>some text here <strong>and here</strong></p> 

Alcuni mesi fa ho creato una function speciale che è la soluzione al tuo problema.

Ecco una function:

 function substr_close_tags($code, $limit = 300) { if ( strlen($code) <= $limit ) { return $code; } $html = substr($code, 0, $limit); preg_match_all ( "#<([a-zA-Z]+)#", $html, $result ); foreach($result[1] AS $key => $value) { if ( strtolower($value) == 'br' ) { unset($result[1][$key]); } } $openedtags = $result[1]; preg_match_all ( "#</([a-zA-Z]+)>#iU", $html, $result ); $closedtags = $result[1]; foreach($closedtags AS $key => $value) { if ( ($k = arrays_search($value, $openedtags)) === FALSE ) { continue; } else { unset($openedtags[$k]); } } if ( empty($openedtags) ) { if ( strpos($code, ' ', $limit) == $limit ) { return $html."..."; } else { return substr($code, 0, strpos($code, ' ', $limit))."..."; } } $position = 0; $close_tag = ''; foreach($openedtags AS $key => $value) { $p = strpos($code, ('</'.$value.'>'), $limit); if ( $p === FALSE ) { $code .= ('</'.$value.'>'); } else if ( $p > $position ) { $close_tag = '</'.$value.'>'; $position = $p; } } if ( $position == 0 ) { return $code; } return substr($code, 0, $position).$close_tag."..."; } 

Ecco DEMO: http://sandbox.onlinephpfunctions.com/code/899d8137c15596a8528c871543eb005984ec0201 (fai clic su "Esegui codice" per verificare come funziona).

Usando @newbieuser per la sua function, ho avuto lo stesso problema, come @ pablo-pazos, che è stato (non) infranto quando $ limit è caduto in un tag html (nel mio caso <br /> in r)

Risolto con qualche codice

 if ( strlen($code) <= $limit ){ return $code; } $html = substr($code, 0, $limit); //We must find a . or > or space so we are sure not being in a html-tag! //In my case there are only <br> //If you have more tags, or html formatted text, you must do a little more and also use something like http://htmlpurifier.org/demo.php $_find_last_char = strrpos($html, ".")+1; if($_find_last_char > $limit/3*2){ $html_break = $_find_last_char; }else{ $_find_last_char = strrpos($html, ">")+1; if($_find_last_char > $limit/3*2){ $html_break = $_find_last_char; }else{ $html_break = strrpos($html, " "); } } $html = substr($html, 0, $html_break); preg_match_all ( "#<([a-zA-Z]+)#", $html, $result ); ...... 

substr (strip_tags ($ content), 0, 100)