0

I was trying to create a script in php, for displaying messages. If the messages includes a web address, then this address I wanted to be displayed as a link. This is my code that works successfuly:

<?php 

if( (substr( $message, 0, 8 ) === "https://") || (substr( $message, 0, 7 ) === "http://") ){
    echo "<a href='$message' target='_blank'> $message </a>"; 
}else{
    echo " $message "; 
}

?> 

It is working perfect if the user inserts in message a web address only like: "http://google.com" The problem starts if the users inserts a text before or after the web address. For example if writes: "visit http://google.com site" then it is making all the phrase as a link and it does not recognises the words with the web address. Any idea how to fix this problem?

1
  • Instead of dumping the whole $message into the "href" attribute, you need to find the longest legal URL starting with "http" (index 0) and only use that portion in the href. Assuming $message always starts at position 0 (you have been copying it to the output 1 character at a time?), you examine it character-by-character to build the longest legal URL, and use that portion of $message in the href. Bonus points for converting a URL Query String back to human-readable characters for the text portion. Commented Jan 28, 2014 at 15:33

3 Answers 3

1

You may use filter_var with FILTER_VALIDATE_URL:

$words = explode(" ", $message);
$_words = array();
foreach($words as $word){
    if(filter_var($word, FILTER_VALIDATE_URL) === false){
    $_words[] = $word;
    }
    else{
    $_words[] = "<a href=\"$word\">$word</a>";
    }
}
echo implode(" ", $_words);

Demo: http://phpfiddle.org/main/code/mu8-vg5

Sign up to request clarification or add additional context in comments.

5 Comments

Any idea how to modify the above code, so that if the user inserts directly a web address like "google.com" without in front of address will also work?
yes it is perfect, I saw this ...but it is not working if someone writes google.com instead of http : //google.com .Is there any posibility to change this so that it will recognizes addresses starting directcly with " www. "
Look at the difference.. 3v4l.org/HWbgG is not working below 5.1.6. Then look at this: 3v4l.org/vJTgr it's easier, cleaner and works for every version of PHP :) @user2491321
@JoranDenHouting If the OP is using the latest version of PHP, it doesn’t matter how many versions support his/her code. Remember that PHP is a server-side script and using new features doesn’t affect the experience of people who visit a website. Now it’ll be kind of you to withdraw the downvote if you’re the one who gave it to my answer.
@SharanyaDutta so how do you know which version he was using?
1

I use this within a class:

public static function CreateLinks($text) {
        return preg_replace('@(https?://([-\w.]+[-\w])+(:\d+)?(/([\w-.~:/?#\[\]\@!$&\'()*+,;=%]*)?)?)@', '<a href="$1" target="_blank">$1</a>', $text);
}

To use it without a class, do this:

$message = preg_replace('@(https?://([-\w.]+[-\w])+(:\d+)?(/([\w-.~:/?#\[\]\@!$&\'()*+,;=%]*)?)?)@', '<a href="$1" target="_blank">$1</a>', $message);

So in a test case this:

$message = "Hello, take a look at http://www.google.com or wait! Maybe you where looking for http://www.bing.com";

$message = preg_replace('@(https?://([-\w.]+[-\w])+(:\d+)?(/([\w-.~:/?#\[\]\@!$&\'()*+,;=%]*)?)?)@', '<a href="$1" target="_blank">$1</a>', $message);

echo $message;

Will output:

Hello, take a look at <a href="http://www.google.com" target="_blank">http://www.google.com</a> or wait! Maybe you where looking for <a href="http://www.bing.com" target="_blank">http://www.bing.com</a>

So, at the end your code can be replaced by just one single line! Replace this:

if( (substr( $message, 0, 8 ) === "https://") || (substr( $message, 0, 7 ) === "http://") ){
    echo "<a href='$message' target='_blank'> $message </a>"; 
}else{
    echo " $message "; 
}

by this:

$message = preg_replace('@(https?://([-\w.]+[-\w])+(:\d+)?(/([\w-.~:/?#\[\]\@!$&\'()*+,;=%]*)?)?)@', '<a href="$1" target="_blank">$1</a>', $message);

Comments

0

Jan Goyvaerts, Regex Guru, describe pretty well in his blog

http://www.regexguru.com/2008/11/detecting-urls-in-a-block-of-text/

To find all matches in a multi-line string, use

preg_match_all('/\b(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)[-A-Z0-9+&@#\/%=~_|$?!:,.]*[A-Z0-9+&@#\/%=~_|$]/i', $subject, $result, PREG_PATTERN_ORDER);
$result = $result[0];

you can use preg_match function to get single match

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.