As in http://drupal.org/node/41651
function valid_url($url, $absolute = FALSE) {
$allowed_characters = '[a-z0-9\/:_\-_\.\?\$,~=#&%\+\@]';
$lowalpha = 'a-z';
$hialpha = 'A-Z';
$alpha = $lowalpha . $hialpha;
$digit = '0-9';
$alphadigit = $alpha . $digit;
$safe = '\$\-\_\.\+';
$extra = '\!\*\'\(\)\,';
$national = '\{\}\|\\\^\~\[\]\`';
$punctuation = '\<\>\#\%\"';
$reserved = '\;\/\?\:\@\&\=';
$hex = $digit . 'A-Fa-f';
$escape = '\%[' . $hex . ']{2}';
$unreserved = $alpha . $digit . $safe . $extra;
$uchar = $unreserved . $escape;
$xchar = $unreserved . $reserved . $escape;
$user = '([' . $unreserved . '\;\?\&\=]|('. $escape . '))+';
$password = '([' . $unreserved . '\;\?\&\=]|('. $escape . '))+';
$login = '(' . $user . '(\:' . $password . ')?\@)?';
$toplabel = '([' . $alpha . ']|([' . $alpha . '][' . $alphadigit . '\-]*[' . $alphadigit .']))';
$domainlabel = '([' . $alphadigit . ']|([' . $alphadigit . ']([' . $alphadigit . '\-])*[' . $alphadigit . ']))';
$hostname = '(' . $domainlabel . '\.)*' . $toplabel;
$port = '[' . $digit . ']+';
$hostnumber = '[' . $digit . ']{1,3}' . '(\.[' . $digit . ']{1,3}){3}';
$host = '(' . $hostname . '|' . $hostnumber . ')';
$hostport = $host . '(\:' . $port . ')?';
$search = '([' . $unreserved . '\;\:\@\&\=]|('. $escape . '))*';
$hsegment = '([' . $unreserved . '\;\:\@\&\=]|('. $escape . '))*';
$hpath = $hsegment . '(\/' . $hsegment . ')*' . '(\?' . $search . ')?';
$proper_url = $login . $hostport . '(\/' . $hpath . ')?';
$protocols = '(http|https|ftp):\/\/';
if ($absolute) {
watchdog('php', preg_match("/^(http|https|ftp):\/\/". $proper_url ."$/i", $url) ? 'Matched' : 'Oops', 0);
return preg_match('/^' . $protocols . $proper_url. '$/i', $url);
}
else {
return preg_match('/^'. $hpath .'$/i', $url);
}
}



