Abreviando um texto sem cortar palavras no PHP

Olá Pessoal!
Como apresentar soluções para problemas cotidianos, é um dos objetivos deste blog, vou compartilhar com vocês uma solução que escrevi para que vocês possam abreviar um texto, sem cortar qualquer palavra pela metade.

É extremamente chato, quando estamos lendo o resumo de uma notícia e nos deparamos com uma palavra cortada, dificultando a compreensão do texto. É feio, principalmente para a estética do layout.

A maioria das funções escritas (em qualquer linguagem) para abreviar um texto, acabam cortando o texto pela metade. Você passa 2 parâmetros: String Texto e Int Limite.

Texto é o texto própriamente dito, e Limite é o tamanho máximo que o texto deve ocupar. Se o texto for maior que 250 caractéres, o script abrevia o texto sem estourar o limite e sem cortar palavras pela metade, caso contrário, deixa o textocomo está.

A solução que escrevi foi esta:

[php]
public function abreviaString($texto, $limite, $tres_p = ‘…’)
{
$totalCaracteres = 0;
//Retorna o texto em plain/text
$texto = Biblioteca::somenteTexto($texto);
//Cria um array com todas as palavras do texto
$vetorPalavras = explode(" ",$texto);
if(strlen($texto) <= $limite):
$tres_p = "";
$novoTexto = $texto;
else:
//Começa a criar o novo texto resumido.
$novoTexto = "";
//Acrescenta palavra por palavra na string enquanto ela
//não exceder o tamanho máximo do resumo
for($i = 0; $i <count($vetorPalavras); $i++):
$totalCaracteres += strlen(" ".$vetorPalavras[$i]);
if($totalCaracteres <= $limite)
$novoTexto .= ‘ ‘ . $vetorPalavras[$i];
else break;
endfor;
endif;
return $novoTexto . $tres_p;
}
[/php]

Note que eu chamei uma função estática chamada somenteTexto(). Quem quiser o fonte dela e saber como ela está implementada, está ai:

[php]
public static function somenteTexto($string)
{
$trans_tbl = get_html_translation_table(HTML_ENTITIES);
$trans_tbl = array_flip($trans_tbl);
return trim(strip_tags(strtr($string, $trans_tbl)));
}
[/php]

Esta é a solução enviada pelo Carlos André Ferrari nos comentários do blog:

[php]
function abreviaString($texto, $limite, $tres_p = ‘…’) {
//Retorna o texto em plain/text
$texto = Biblioteca::somenteTexto($texto);

if (strlen($texto) <= $limite)
return $texto;
return array_shift(explode(‘||’, wordwrap($texto, $limite, ‘||’))) . $tres_p;
}
[/php]

É importante que, antes de abreviarmos um texto, recebermos o texto puro, livre de tags htmls, scripts ou qualquer outra coisa que não faça parte do texto. Quando isso ocorre, dificulta a abreviação pois o algoritmo não sabe o que é texto e o que é metacaracter.

E é isso aí pessoal, o código está bem comentádo e documentado, caso vocês tenham alguma dúvida, fiquem a vontade para perguntar nos comentários.

Qualquer outra implementação que vocês tenham, que faça a mesma coisa, até mesmo em outras linguagens, o share é totalmente bem-vindo.

[]’s
Igor.

16 thoughts on “Abreviando um texto sem cortar palavras no PHP

  1. Olá, Igor.

    Realmente palavras pela metade ficam bem deselegantes. Porém, creio que a função “wordwrap” do próprio PHP já ajude com isso. O único complemento seria incluir os três pontos, caso ocorreu redução do texto.

    Outra solução alternativa que vi recentemente é baseada em CSS 3. Escrevi sobre isso lá no meu blog. A visita é bem vinda:
    http://rubsphp.blogspot.com/2011/08/text-overflow.html

    A vantagem dela é que o texto é quebrado de acordo com a largura do navegador (e do espaço reservado ao texto), e a quebra fica por conta do próprio navegador realizar.

    Like

    1. Olá Rubéns!

      O método wordwrap não serve para “abreviar” um texto e sim para forçar a quebra de linha ou algo do gênero.

      Utilização boa do wordwrap é quando não queremos que uma palavra muito grande anule o “truncate” automático do browser.

      $text = "A very long woooooooooooord.";
      $newtext = wordwrap($text, 8, "\n", true);
      echo "$newtext\n";

      A very
      long
      wooooooo
      ooooord.

      A função que eu passo acima ela faz outra coisa.

      Ela limpa os metacaracteres da string, corta a atring e quando corta ela não deixa palavras pela metade, entendeu?

      Like

  2. sempre usei a wordwrap:

    function abreviaString($texto, $limite, $tres_p = ‘…’) {
    if (strlen($texto) <= $limite) return $texto;
    return array_shift(explode('||', wordwrap($texto, $limite, '||'))) . $tres_p;
    }

    echo abreviaString('O rato roeu a roupa do rei de roma', 50);

    Like

  3. Parabéns pelos artigos, mas eu cortaria a frase a um limite considerável (depende do layout em questão) e usaria o bom e velho CSS para resolver o problema, assim como o google faz no gMail/gDocs 😀

    Like

  4. Muito legal cara, vou estudar mais sobre isso. Estou montando um portal no WordPress e um dos problemas que venho enfrentando é sobre isso, definir um número de caracteres não resolveu 100%.

    Agora vou ver como consigo aplicar isso no WordPress, tem alguma dica?

    Obrigado pelo post de qualquer forma!

    Like

  5. Eu não sabia como utilizar wordwrap para este fim e sempre fiz de forma semelhante ao que o Igor escreveu, valeu Carlos! Valeu também Igor!

    Bruno, o the_excerpt(); do WordPress já faz o efeito previsto neste post, retorna um limite sem cortar palavras.

    Like

  6. Sempre vejo os posts do Igor Escobar, ajuda muito quem está iniciando PHP, e esta função aí é super interessante. Valeu Carlos & Igor.

    Like

  7. Estou com uma dúvida, estou usando o while do SQL e ele me retorna um erro desse tipo: ” Fatal error: Cannot redeclare abreviaString() (previously declared in..”

    Like

  8. poxa
    que função que me ajudou muito
    valeu meu queridão

    Att,
    Cornélio José Wiedemann ( TI & DBA )

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: