Hola Comunidad:
Les presento una clase para evitar el spam en nuestros formularios web sin usar captcha.
Hay muchas personas tienen dificultades visuales y un captcha le complica las cosas.
Esta clase entrega un karma al formulario e indica de acuerdo a ese índice si es spam o no.
antispam.class.php Código PHP:
<?php
class antispam
{
var $tolerancia=2;
var $totalPalabras=0;
var $puntos=0;
var $listOut = '/(
href|fast|accurate|expen|free|excite|increase|brochure|magazine|energy|loan|mortgage|classif|income|incomi|debt|affiliat|afford|insurance|member|bachelor|opportunit|winner|congrat|horny|viagra|víagra|vìagra|viagr@|vi@gra|v1agra|porn|slut|wom|leverage|investment|instantly|cash|muscle|lotto|finance|dollar|millionaire|buck|gambl|advertise|currency|prosperity|prosperous|invitation|reward|bigger|better|purchase|prescription|pharmacy|poker|penis|approve|enlarge|promotions|congress|coupon|bulk|girlz|goddess|webcam|livecam|camera|auction|chick|fuck|cock|pleasure|remedy|hormone|therapy|remove|dismiss|asian|mailerdirect|forfree|freehost|sexserver|orgasm|cheap|discount|vioxx|xanax|zolus|levitra|levitra |enlarge|chatroom|booker|credit-card-debt|discreetordering|paxil|xxx|v i a g r a)/';
function antispam($tolerancia) {
$this->tolerancia=(int)$tolerancia;
}
function ControlUrl($dominio,$url) {
$longitudDominio = strlen($dominio);
$urlRecomendada = substr($url,0,$longitudDominio);
if ($urlRecomendada == $dominio)
return true;
else
return false;
}
function textCleaner($text) {
$text = strip_tags( $text );
return $text;
}
function controlPalabras($text) {
if($coin = preg_match_all($this->listOut,$text,$coincidencias))
$this->puntos += $coin;
$this->totalPalabras += str_word_count($text,0,'/-_@:."$%&()=?¡¿!#{}[]+-*><');
}
function karma() {
if (round($this->puntos/$this->totalPalabras,2) > ($this->tolerancia/10))
return true;
else
return false;
}
function valida_email($email){
$exp = "^[a-z0-9]+([\._\-][a-z0-9]+)*@([a-z0-9]+([\._\-][a-z0-9]+))+$";
if(eregi($exp,$email)){
if(checkdnsrr(array_pop(explode("@",$email)),"MX")){
return true;
}else{
return false;
}
}else{
return false;
}
}
}
?>
La clase tiene varias funciones interesantes:
ControlUrl($dominio,$url);
Esta función es para cuando usas "recomeinde este sitio a un amigo", seguramente en el form tienes un campo oculto con la URL a recomendar.
Entonces lo que hace es tomar esa url y fijarse si en el comienzo de la URL esta tu dominio (esto es para que no recomienden sitio que no son tuyos, spam)
textCleaner($text);
Limpia de la cadena (nombre, mensaje, etc) etiquetas html y php
controlPalabras($text);
Esta función evalúa una cadena (palabra por palabra) y se fija si en esa cadena hay algunas de las palabnras consideradas spameras y además va contando el total de las palabras del formualrio
karma();
Esta funcion le asigna un karma. Toma la cantidad de palabras de spam encontradas y la divide por el total de palabras del form en los campos controlados. Si el karma es mayor a la tolerancia entonces devuelve
true.
La tolerancia se configura al crear un objeto. Va del 1 en adelante, mientras mayor sea el número maytor será la tolerancia valida_email($email);
Valida los emails del form
Veamos cómo se usa aplicándolo al famoso "recomeinde este sitio a un amigo".
Los campos del formulario que se han enviado son:
-friendname
-friendemail
-yourname
-youremail
-subject
-recurl (campo oculto)
Vamos al código (se supone que ya han enviado el formulario y lo vamos a procesar):
Código PHP:
// Incluimos la clase
include_once("antispam.class.php");
// instanciamos el objeto indicando la tolerancia del 1 en adelante
$noSpam = new antispam(3);
if (!$noSpam->ControlUrl('http://www.midominio.com',$_POST['recurl']))
die('acceso incorrecto!');
// Limpiemos los textos
$url = $noSpam->textCleaner($_POST['recurl']);
$nombre_amigo = $noSpam->textCleaner($_POST['friendname']);
$su_nombre = $noSpam->textCleaner($_POST['yourname']);
$su_email = $noSpam->textCleaner($_POST['youremail']);
$titulo = $noSpam->textCleaner($_POST['subject']);
// En busqueda de la puntuación
$noSpam->controlPalabras($url);
$noSpam->controlPalabras($nombre_amigo);
$noSpam->controlPalabras($su_nombre);
$noSpam->controlPalabras($titulo);
$noSpam->controlPalabras($su_email);
if ($noSpam->karma())
die ('Ups! se ha detectado intento de spam');
if (!$noSpam->valida_email($_POST['youremail']))
{
die ('Su email no es válido');
}
if (!$noSpam->valida_email($_POST['friendemail']))
{
die('el email de tu amigo no es válido');
}
Obviamente yo he tratado a los erroresw con "die()" pero tu deberás adaptarlo a la manera de mostrar los errores en tus formularios.
Espero sus comentarios y/o aportes.
Saludos!!