Как правильно защитить форму от спама?
Hidden-инпуты для защиты от спама - это фигня. Больше половины ботов раскусят.
Я на многих сайтах ставлю довольно простую защиту, которая отлично работает.
Добавь в форму какой-нибудь текстовый инпут и скрой его стилями, но НЕ ЮЗАЙ display: none;, visibility:hidden;, opacity:0;, так как многие боты и это раскусят.

Например input с name="copyemail":
<form action="">
	<input type="text" name="copyemail" placeholder="Email для копии">
	<input type="text" name="name" placeholder="Имя">
	<input type="email" name="email">
	<button type="submit">Отправить</button>
</form>
и стили для него:
input[name="copyemail"] {
    display: block;
    width: 2px;
    height: 2px;
    margin-bottom: -2px;
    border: none;
    padding: 0;
    opacity: 0.01;
}

И дальше уже на сервере проверяешь:
if ($_POST['copyemail']) {    
    //Это спам! Делаем вид, что сообщение отправлено.
    die('Ваше сообщение отправлено');
} else {
     //Все норм. Метро Люблино, работаем
}
Вне зависимости от капч и прочих технических средств определения живого пользователя - стоит подумать головой, чем отличается то, что вам реально может написать клиент, от того, что пришлет спам-бот.
Например, если в тексте клиента крайне маловероятен фрагмент "http" - можно обойтись и вовсе без капчи... а боты пусть радостно шлют свой шлак в /dev/null.