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:

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;
}

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

    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)));
    }

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

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;
}

É 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.

software engineer @hole19golf, #javascript #nodejs #ruby #java #php #scala #python

Twitter LinkedIn 

Be Sociable, Share!

Posts Relacionados:

15 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.

  2. 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?

  3. 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);

  4. 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 😀

  5. 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!

  6. 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.

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

  8. 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..”

Leave a Reply

Your email address will not be published. Required fields are marked *