In my experience the currently most effective methods are honeypot input fields that are made invisible to users via CSS (best use several different methods, such as visibility:hidden, setting a size of 0 pixels, and absolute positioning far outside the browser window); if they're filled anyway you can assume it's a spambot.
This blog describes a rather complex method that I've tried out myself (with 100% success so far), but I suspect that you could get the same result by skipping all the stuff with hashed field names and just add some simple honeypot fields.
This is simple trick to block spam bot or brute force attack without using captcha.
Put this in your form:
<input type="hidden" name="hash" value="<?php echo md5($secret_key.time()).','.time(); ?>" />
Put this in your php code
$human_typing_time = 5;/** page load (1s) + submit (1s) + typing time (3s) */
$vars = explode(',', $_POST['hash']);
if(md5($secret_key.$vars[1]) != $vars[0] || time() < $var[1] + $human_typing_time){
//bot?
exit();
}
Depend on weight of form you can increase or decrease $human_typing_time.