The most widely workable and accepted spam method is to use a hidden input field. The way spam bots work is one of 2 ways (not including mechanical turk based spam, which is "impossible" to prevent): POST data to common forum registration URLs and hope it works, or load up the registration page and attempt to parse the fields then work out what they expect, this is done based on common words. For example, they look for fields with "email" and enter email, "password" and enter password etc etc. but there's one problem with this: bots
do not parse page styling so what you can do is create fake input fields and hide them with CSS.
Here's a very basic example that will beat most general spam bots, of course you have issues with ones that are targeting this forum specifically but as with mechanical turk it's unsolvable without a lot of leg work.
Code:
<form method="POST" action="">
<label for="username">username</label><input type="text" name="username" value="" id="username" />
<label for="real_username">username</label><input type="text" name="real_username" value="" id="real_username" />
<label for="password">password</label><input type="password" name="password" value="" id="password" />
</form>
So as you can see if you were to load that up in your browser now you would see:
username: [input]
username: [input]
password: [input]
and if a bot were to load the page it would "see" the following fields:
username
real_username
password
and because username matches what it thinks the username would be likely to go into it fills that field, it might or might not fill in real_username and it fills in password.
Now what if we were to hide the first username from the user using css?
Code:
<style>
#real_username{
display:none;
}
</style>
Now when a user loads the page containing the HTML from above they see:
username: [input]
password: [input]
but the bot doesn't parse CSS so it again sees:
username
real_username
password
So now we know when a request is made the registration process and "username" is filled in that it's a bot, because users can only fill in the input box "real_username". Then what you do in the logic part of the registration is:
Code:
<?php
if($_POST['username'])
{
$member_group = 2;
}
?>
where member group 2 is a group "spammers" that requires moderator approval on posts.
BAM instant spam protection!
There is one flaw with this method, if a user is using some sort of screen reading program they will have problems, but with notices on the page about it and the accounts not being discarded only flagged as spammers it's fine.