Server-side Text Linkification with PHP
I began writing the Linkification extension for Firefox after browsing several message boards and comment areas, and becoming frustrated at the number of plain text links. I just wanted to click the text like any other link, rather than having to highlight, copy, and paste the text into the address bar. I don't know how many people are immediately put off by text links, but I do know that I'm personally more likely to visit a site if all I have to do is click once.
While coding my comment system, I knew I didn't want to deal with the potential security risk of allowing users to post certain HTML tags, most notably <a>. I also knew that not everyone would be using Firefox, and even fewer visitors would have Linkification installed. Instead of relying on client-side javascript, I ported the javascript logic from Linkification to a server-side PHP function.
The PHP LinkifyText() function
<?php
function LinkifyText($sText, $aAttributes = array('title' => 'Linkified Text', 'rel' => 'nofollow'), $aProtocols = array('http:\/\/', 'https:\/\/', 'ftp:\/\/', 'news:\/\/', 'nntp:\/\/', 'telnet:\/\/', 'irc:\/\/', 'mms:\/\/', 'ed2k:\/\/', 'xmpp:', 'mailto:'), $aSubdomains = array('www'=>'http://', 'ftp'=>'ftp://', 'irc'=>'irc://', 'jabber'=>'xmpp:'))
{
$sRELinks = '/(?:(' . implode('|', $aProtocols) . ')[^\^\[\]{}|\\"\'<>`\s]*[^!@\^()\[\]{}|\\:;"\',.?<>`\s])|(?:(?:(?:(?:[^@:<>(){}`\'"\/\[\]\s]+:)?[^@:<>(){}`\'"\/\[\]\s]+@)?(' . implode('|', array_keys($aSubdomains)) . ')\.(?:[^`~!@#$%^&*()_=+\[{\]}\\|;:\'",<.>\/?\s]+\.)+[a-z]{2,6}(?:[\/#?](?:[^\^\[\]{}|\\"\'<>`\s]*[^!@\^()\[\]{}|\\:;"\',.?<>`\s])?)?)|(?:(?:[^@:<>(){}`\'"\/\[\]\s]+@)?((?:(?:(?:(?:[0-1]?[0-9]?[0-9])|(?:2[0-4][0-9])|(?:25[0-5]))(?:\.(?:(?:[0-1]?[0-9]?[0-9])|(?:2[0-4][0-9])|(?:25[0-5]))){3})|(?:[A-Fa-f0-9:]{16,39}))|(?:(?:[^`~!@#$%^&*()_=+\[{\]}\\|;:\'",<.>\/?\s]+\.)+[a-z]{2,6}))\/(?:[^\^\[\]{}|\\"\'<>`\s]*[^!@\^()\[\]{}|\\:;"\',.?<>`\s](?:[#?](?:[^\^\[\]{}|\\"\'<>`\s]*[^!@\^()\[\]{}|\\:;"\',.?<>`\s])?)?)?)|(?:[^@:<>(){}`\'"\/\[\]\s]+:[^@:<>(){}`\'"\/\[\]\s]+@((?:(?:(?:(?:[0-1]?[0-9]?[0-9])|(?:2[0-4][0-9])|(?:25[0-5]))(?:\.(?:(?:[0-1]?[0-9]?[0-9])|(?:2[0-4][0-9])|(?:25[0-5]))){3})|(?:[A-Fa-f0-9:]{16,39}))|(?:(?:[^`~!@#$%^&*()_=+\[{\]}\\|;:\'",<.>\/?\s]+\.)+[a-z]{2,6}))(?:\/(?:(?:[^\^\[\]{}|\\"\'<>`\s]*[^!@\^()\[\]{}|\\:;"\',.?<>`\s])?)?)?(?:[#?](?:[^\^\[\]{}|\\"\'<>`\s]*[^!@\^()\[\]{}|\\:;"\',.?<>`\s])?)?))|([^@:<>(){}`\'"\/\[\]\s]+@(?:(?:(?:[^`~!@#$%^&*()_=+\[{\]}\\|;:\'",<.>\/?\s]+\.)+[a-z]{2,6})|(?:(?:(?:(?:(?:[0-1]?[0-9]?[0-9])|(?:2[0-4][0-9])|(?:25[0-5]))(?:\.(?:(?:[0-1]?[0-9]?[0-9])|(?:2[0-4][0-9])|(?:25[0-5]))){3})|(?:[A-Fa-f0-9:]{16,39}))))(?:[^\^*\[\]{}|\\"<>\/`\s]+[^!@\^()\[\]{}|\\:;"\',.?<>`\s])?)/i';
$sAttributes = '';
while (list($sKey, $sValue) = each($aAttributes))
{
$sAttributes .= ' ' . $sKey . '="' . $sValue . '"';
}
$sNewText = '';
while (preg_match($sRELinks, $sText, $aMatches))
{
$nMatchType = sizeof($aMatches) - 1;
$sMatchText = $aMatches[$nMatchType];
$sNewText .= substr($sText, 0, strpos($sText, $aMatches[0]));
$sText = substr($sText, strpos($sText, $aMatches[0]) + strlen($aMatches[0]));
if ($nMatchType == 1)
{
$sNewText .= '<a href="' . $aMatches[0] . '"' . $sAttributes . '>' . $aMatches[0] . '</a>';
}
elseif ($nMatchType == 2)
{
$sNewText .= '<a href="' . $aSubdomains[$sMatchText] . $aMatches[0] . '"' . $sAttributes . '>' . $aMatches[0] . '</a>';
}
elseif (($nMatchType == 3) || ($nMatchType == 4))
{
$sNewText .= '<a href="http://' . $aMatches[0] . '"' . $sAttributes . '>' . $aMatches[0] . '</a>';
}
else
{
$sNewText .= '<a href="mailto:' . $aMatches[0] . '"' . $sAttributes . '>' . $aMatches[0] . '</a>';
}
}
return $sNewText . $sText;
}
?>
LinkifyText() Examples
<?php
print LinkifyText('This is a test link: http://example.com');
print LinkifyText('This is a test link: www.example.com');
print LinkifyText('This is a test link: ftp.example.com');
print LinkifyText('This is a test link: example.com/test/');
print LinkifyText('This is a test link: email@example.com');
?>


standards-based web development and design ideas


× 
2 Comments
Hey, I really love this function, it has helped me a lot!
I like your Linkification addon for Firefox too, I recommend it to all my Firefox friends (users).
Thank you again, because this is what I was looking for :)
Thanks for the script. I'm working on my company intranet and will use the code there. I appreciated the time and effort you've put into the coding of linkification (and this php script).
Steve
Comments are disabled for this entry.