Comment span comes in many forms. That's just one of them. You can do a dozen or so "or's" or you can use preg_match() to look specifically for the URL. Then you can save your or's for even more filters:
// Define a semi-global array so you can update it as you need it.
// It's more of a configuration.
$form_spam = Array (
'\[\s*URL.*\]*',
'\[\s*LINK.*\]*',
'\%5B\s*URL.*(\%5D)*',
'\%5B\s*LINK.*(\%5D)*',
'\[\s*a\s*href.*\]*',
'\%5B\s*a\s*href.*(\%5B)*',
'\<\s*a\s*href.*\>*',
'\%3C\s*a\s*href.*(\%3E)*'
);
Then wherever your form submits, call the function to use this array to check against.
$is_spam = check_for_urls($form_spam);
if ($is_spam) { wp_die( __('Error: Please do not enter a URL.') ); }
The function accepts your array as a parameter, and loops through the patterns.
function check_for_urls($patterns){
$spam = null;
foreach ($_POST as $key => $value) {
foreach ($patterns as $v) {
if (preg_match("/$v/i",stripslashes($_POST[$key]))) {
$spam_in = 1;
break;
}
}
}
return $spam;
}
This will not just check ONE field, it will check them all, and is case-insensitive. If you have a field that specifically allows a URL pattern, you'll have to skip it in the loop.
You can extend this to other patterns too:
$bad_patterns = Array (
'b*cc\s*:',
'to\s*:',
'content\-type',
'\[\s*URL.*\]*',
'\[\s*LINK.*\]*',
'\%5B\s*URL.*(\%5D)*',
'\%5B\s*LINK.*(\%5D)*',
'\[\s*a\s*href.*\]*',
'\%5B\s*a\s*href.*(\%5B)*',
'\<\s*a\s*href.*\>*',
'\%3C\s*a\s*href.*(\%3E)*',
'example.com',
'viagra',
'pharm',
'male\s+enhance'
);
"example.com" = your domain name, the reason being, you'll never submit a comment to your self and a common ploy is to use anything@yourdomain.com in spam.
I will add that wp_die (or any die on error) is not very user friendly (and is lazy) as it forces the user to use their back button. What should happen there is if there's an error, it returns to the form with fields populated.