Convert a string url to hyperlink

Asked

Viewed 1,263 times

1

Works for several links but if I put the same 2x link in the string does not work as do?

function MontarLink($texto)
{
       if (!is_string ($texto))
           return $texto;

    $er = "/(https:\/\/(www\.|.*?\/)?|http:\/\/(www\.|.*?\/)?|www\.)([a-zA-Z0-9]+|_|-)+(\.(([0-9a-zA-Z]|-|_|\/|\?|=|&)+))+/i";

    preg_match_all ($er, $texto, $match);

    foreach ($match[0] as $link)
    {

        //coloca o 'http://' caso o link não o possua
        $link_completo = (stristr($link, "http") === false) ? "http://" . $link : $link;

        $link_len = strlen ($link);

        //troca "&" por "&", tornando o link válido pela W3C
       $web_link = str_replace ("&", "&", $link_completo);
       $texto = str_ireplace ($link, "<a href=\"" . strtolower($web_link) . "\" target=\"_blank\">". (($link_len > 60) ? substr ($web_link, 0, 25). "...". substr ($web_link, -15) : $web_link) ."</a>", $texto);

    }

    return $texto;

}

echo MontarLink("ola mundo www.cade.com.br"); // ESSE FUNCIONA!!!
echo "<br><br>";
echo MontarLink("ola mundo www.cade.com.br outro site www.terra.com.br "); // ESSE FUNCIONA!!!
echo "<br><br>";
echo MontarLink("ola mundo www.cade.com.br mesmo site www.cade.com.br"); // NÃO FUNCIONA!!!
  • 1

    COTD: //troca "&" por "&", tornando o link válido pela W3C

  • @bfavaretto Poxa... I’m talking about the same string guys... echo Montarlink("ola mundo www.cade.com.br --- second site www.cade.com.br third site www.cade.com.br");

  • It actually seems to be working yes: http://ideone.com/pxSws9

  • 2

    @bfavaretto guy looks that sinister!!! I found the error.. the error is if it is 2 links equal!!! I put here 2 different links and it worked.. but with 2 equal links he of the stick... for it will be?

  • I made some edits in the code to facilitate... see at the end the 3 echo.

  • Mark one of the answers as accepted. Your problem today may be someone’s tomorrow and have an answer marked as accepted help in the decision.

Show 1 more comment

2 answers

5

The problem is that when you find the first occurrence, you’re replacing them all, then you get the second repeated occurrence and you have them replaced again, and you go into a chain reaction, messing everything up...

Use the function preg_replace_callback:

function MontarLink($texto)
{
       if (!is_string ($texto))
           return $texto;

    $er = "/(https:\/\/(www\.|.*?\/)?|http:\/\/(www\.|.*?\/)?|www\.)([a-zA-Z0-9]+|_|-)+(\.(([0-9a-zA-Z]|-|_|\/|\?|=|&)+))+/i";

    $texto = preg_replace_callback($er, function($match){
        $link = $match[0];

        //coloca o 'http://' caso o link não o possua
        $link = (stristr($link, "http") === false) ? "http://" . $link : $link;

        //troca "&" por "&", tornando o link válido pela W3C
        $link = str_replace ("&", "&amp;", $link);

        return "<a href=\"" . strtolower($link) . "\" target=\"_blank\">". ((strlen($link) > 60) ? substr ($link, 0, 25). "...". substr ($link, -15) : $link) ."</a>";
    },$texto); 

    return $texto;

}

echo MontarLink("ola mundo www.cade.com.br"); // ESSE FUNCIONA!!!
echo "<br><br>";
echo MontarLink("ola mundo www.cade.com.br outro site www.terra.com.br "); // ESSE FUNCIONA!!!
echo "<br><br>";
echo MontarLink("ola mundo www.cade.com.br mesmo site www.cade.com.br"); // ESSE FUNCIONA!!!
  • thanks!! now yes it’s top!!!

3

I did some digging and found that answer in Stack Overflow which in addition to solving your text-to-link problem still takes into account various particularities of a URL and even covers links of the type mailto, if anyone still uses them.

The original answer had some silly misconceptions which I fixed and will be making available here:

function makeClickableLinks( $text ) {

    $text = ' ' . html_entity_decode( $text );

    // Full-formed links

    $text = preg_replace(

        '#(((f|ht){1}tps?://)[-a-zA-Z0-9@:%_\+.~\#?&//=]+)#i',

        '<a href="\\1" target=_blank>\\1</a>',

        $text
    );

    // Links without scheme prefix (i.e. http://)

    $text = preg_replace(

        '#([[:space:]()[{}])(www.[-a-zA-Z0-9@:%_\+.~\#?&//=]+)#i',

        '\\1<a href="http://\\2" target=_blank>\\2</a>',

        $text
    );

    // E-mail links (mailto)

    $text = preg_replace(

        '#([_\.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,3})#i',

        '<a href="mailto:\\1" target=_blank>\\1</a>',

        $text
    );

    return $text;
}

You can use it the same way you’ve been using it:

// Link com prefixo http:// e um mailto:

echo makeClickableLinks('

    This is a test clickable link: http://www.websewak.com  You can also try using an email address like [email protected]'
), '<br />';

// Links sem o prefixo http://

echo makeClickableLinks( 'www.cade.com.br' ), '<br />';

// Mais de um link no mesmo texto

echo makeClickableLinks(

    'ola mundo www.cade.com.br outro site www.terra.com.br'
), '<br />';

// Dois links iguais

echo makeClickableLinks(

    'ola mundo http://www.cade.com.br mesmo site http://www.cade.com.br'
), '<br />';
  • Perfect!! Vlw!!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.