validar email en PHP

  • Por
Comprobar la validez de una dirección de correo electrónico, es decir, validar la buena redacción de un email.
Vamos a ver una función muy útil en PHP que sirve para comprobar la validez de un correo. En realidad comprueba si una dirección de correo electrónico está bien escrita sintácticamente, dejando de lado las comprobaciones de si ese mail existe o no realmente, que no se pueden hacer tan fácilmente.

Vamos a escribir una función que se llama comprobar_email y recibe la cadena de texto con el email que queremos validar. Si dicho email es correcto desde el punto de vista sintáctico, es decir, si tiene un nombre de usuario, una arroba y una terminación con el nombre de un dominio o subdominio, etc, devolverá un 1, es decir, verdadero. En caso de que el email no esté correctamente escrito, la función devolvería 0, que equivale a falso.

La función en si da por hecho inicialmente que el email es erróneo y realiza una serie de comprobaciones que, si todas responden correctamente, dan por conclusión que el email sí estaba bien escrito. Si alguna de esas comprobaciones no era correcta, no se llegaría al final de las comprobaciones y quedaría el resultado como se ha supuesto en un principio, es decir, como incorrecto.

código de la función

function comprobar_email($email){
    $mail_correcto = 0;
    //compruebo unas cosas primeras
    if ((strlen($email) >= 6) && (substr_count($email,"@") == 1) && (substr($email,0,1) != "@") && (substr($email,strlen($email)-1,1) != "@")){
       if ((!strstr($email,"'")) && (!strstr($email,"\"")) && (!strstr($email,"\\")) && (!strstr($email,"\$")) && (!strstr($email," "))) {
          //miro si tiene caracter .
          if (substr_count($email,".")>= 1){
             //obtengo la terminacion del dominio
             $term_dom = substr(strrchr ($email, '.'),1);
             //compruebo que la terminación del dominio sea correcta
             if (strlen($term_dom)>1 && strlen($term_dom)<5 && (!strstr($term_dom,"@")) ){
                //compruebo que lo de antes del dominio sea correcto
                $antes_dom = substr($email,0,strlen($email) - strlen($term_dom) - 1);
                $caracter_ult = substr($antes_dom,strlen($antes_dom)-1,1);
                if ($caracter_ult != "@" && $caracter_ult != "."){
                   $mail_correcto = 1;
                }
             }
          }
       }
    }
    if ($mail_correcto)
       return 1;
    else
       return 0;
}


Las comprobaciones

En el primer if compruebo que el email tiene por lo menos 6 caracteres (el mínimo), que tiene una arroba y sólo una y que no está colocada ni al principio ni al final.

En el segundo if comprueba que no tiene algunos caracteres no permitidos. Y los restantes hacen comprobaciones de las distintas partes de la dirección de correo, a saber: Que hay un punto en algún lado y que la terminación del dominio es correcta y que el principio de la dirección también es correcto.

Finalmente, se devuelve la variable local utilizada para guardar la validez o incorrección del correo.

Descarga del script

La persona que lo desee, puede descargar el archivo con el código fuente de este script, para utilizarlo en sus aplicaciones web.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir

Comentarios

sQalo

09/12/2002
Otra forma mas "sencilla de hacerlo". Con expresiones regulares.

if ((!ereg("^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*$", $email)) or (!getmxrr($emailhost1, $mxhostarr)))
    $mensajeerror .= "ERROR, $email no es una direccion válida";

Juam R

20/11/2003
Mejor utiliza esta:

"^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]{2,200}\.[a-zA-Z]{2,6}$"

moz

05/10/2004
Con esta ademas dejas que pasen emails con subdominios (soibre todo para los gratuitos) del tipo mail@finka.homeip.net

function ValidaMail($pMail) {
    if (ereg("^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@+([_a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]{2,200}\.[a-zA-Z]{2,6}$", $pMail ) ) {
       return true;
    } else {
       return false;
    }
}

Fernando Cuadrado

08/4/2005
Doy fe por el de "MOZ", funciona correctamente.

Gracias MOZ.

Cristina

06/6/2005
La expresión regular de "MOZ" deja pasar e-mails con mas de una @ seguidas. Del tipo user@@dominio.com

Souza SED

22/7/2005
CODIGO
<!--
//VALIDAMOS LOS E-MAILS RECIBIDOS
function validar_mail(&$email){
global $error_email;
$email=trim($email);
$email=strtolower($email);
$email=addslashes($email);
if(!$email){
$error_email= "- Rellene este campo.";
}else{
if(!eregi("^[a-zA-Z0-9]+[a-zA-Z0-9_.-]+[a-zA-Z0-9]+@[a-zA-Z0-9]+[a-zA-Z0-9-]+[a-zA-Z0-9.-]+[a-zA-Z0-9]+.[a-z]{2,4}$", $email)){
$error_email= "- E-mail incorrecto.";
}
}
}
//-->

He realizado una función de patrones de expresiones regulares que os puede ser muy útil para validar los E-mails. He tenido en cuenta detalles como no permitir el inicio del email por _ ó - ó . pues no suele ser habitual que los proovedores de correo lo permitan a la hora de darse de alta, al igual que dejar _ ó - ó . antes de la "@" y por tanto despues tampoco. Si se permiten los correos tipo correo.loquesea@server.subdomain.dtl
correo_loquesea@server-subdomain.dtl

El problema es que para permitir estas conbinaciones también debo dejar combinaciones erroneas como
correo_.loquesea@server-.subdomain.dtl
ya que el caracter - me da problemas a la hora de restringirlo. Supongo que será un error de php.
Es muy curioso si escribo "^[a-zA-Z0-9_-.]..." no me reconoce el caracter guion - ahora si lo pongo así "^[a-zA-Z0-9_.-]..." si que lo hace... jejejeje. De todas formas es muy poco probable que el usuario se moleste en combinar estos caracteres para dar un falso email . Y como punto final habia pensado indicar una lista de los tdl más comerciales y más usados para que la terminación del e-mail siempre fuera .com .net etc.... pero lleva mucha faena y es tonteria porque si nos la quieren meter nos la meten doblada... a no ser que pongas muchas condiciones y lo unico que conseguiras es una lista muy pequeñita de usuarios...jejejejeje mas vale tener un email que otro erroneo y no pocos pues puedes perder usuarios con emails raros gratuitos.

Espero que os haya servido de ayuda.
By Souza
www.clased.com
www.rocsite.net

Souza SED

22/7/2005
function validar_mail(&$email){
global $error_email;
$email=trim($email);
$email=strtolower($email);
$email=addslashes($email);
if(!$email){
$error_email= "Rellene este campo.";
}
else
{

if(!eregi("^[a-zA-Z0-9]+[a-zA-Z0-9_.-]+[a-zA-Z0-9]+@[a-zA-Z0-9]+[a-zA-Z0-9-]+[a-zA-Z0-9.-]+[a-zA-Z0-9]+.[a-z]{2,4}$", $email)){
$error_email= "- E-mail incorrecto.";
}
}
}

A ver si ahora es más legible el código. Sorry. Es la primara vez que escribo aqui.

Souza SED

26/7/2005
//VALIDAMOS LOS E-MAILS RECIBIDOS ESTE SI ES VÁLIDO
function validar_mail(&$email){
  global $error_email;
  $email=trim($email);
  $email=strtolower($email);
  $email=addslashes($email);
  if(!$email){
    $error_email= "- Rellene este campo.";
  }else{
  if(!eregi("^[a-z]+[_\.\-]{0,1}[a-z0-9]+@[a-z0-9]+[_\.\-]{0,1}[a-z0-9]+\.[a-z]{2,4}$", $email)){
    $error_email= "- E-mail incorrecto.";
  }
  }
}

BETTO

12/12/2005
posiblemente resulte esta validación
$texto_mail
$mail=strpos("@",$texto_mail);
if($mail===false) echo "mail no valido";

espero coentarios
gracias

NeZ

12/3/2006
El de Moz se cae al escribir @@, hay que quitarle el +

georkis

04/12/2006
Esta muy interesante el script, pero le falta algo muy importante. ¿cómo va a saber el usuario que tipo d error que ha cometido? hace falta imprimir los resultados de la dirección del correo. Esta script la probé, pero no así, pero me ha dado una idea genial... Grasias MOZ

iñaki

26/7/2007
muy buenos los algoritmos, pero lo único que comprueban es que la sintaxis sea la correcta, ahi va uno que ademas mira si el dominio existe. Me falta preguntarle al dominio si el usuario es válido, a ver si a alguien se le ocurre.

function ValidaEmail($email)
{
$valida=false;
if (ereg("^[_a-zA-Z0-9-]+(.[_a-zA-Z0-9-]+)*@+([_a-zA-Z0-9-]+.)*[a-zA-Z0-9-]{2,200}.[a-zA-Z]{2,6}$", $email ))
{
$cr=split("@",$email);
$dominio=$cr[1];
$validar = @fsockopen($dominio, 80, $errno, $errstr, 5);
if ($validar)
{
$valida=true;
fclose($validar);
}
}
return $valida;
}

Saúl

10/12/2007
La de Moz esta muy bien, me sirvio para ver unos errores que tenía, sin embargo falla en algunos casos, da como válidas:
_soy_saul@algo.com
_soy_saul@_algo.otro.com

y lo que ya mencionaron del arroba


creo que la mía es casi infalibre:
^[[:alnum:]]+((.|_)[[:alnum:]]+)*@([[:alnum:]]+.)+[[:alnum:]]{2,6}$

Jean (AuralSolutions)

08/4/2009
Validación email completa!
Con esta expresión regular se puede validar desde un email hasta una lista de emails separados por comas o punto y coma;

// Expresión regular para definir el formato de un email individual
$er_email = '(([A-Za-z0-9]+[a-zA-Z0-9_.-]*[A-Za-z0-9]+)@([A-Za-z0-9]+[a-zA-Z0-9.-]*[A-Za-z0-9]+).([a-zA-Z]{2,6}))';

// Con esto permitimos que pueda haber una lista de emails
$er = "^".$er_email."( ?[;,] ?".$er_email.")*$";

Manuel

27/4/2009
el patrón de Saúl también tiene una excepción
El patrón de Saúl deja pasar direcciones con espacios en blanco: "aaa ee e@dominio.es"

mjzorrilla

12/8/2009
integrar codigo de verificacion de mail en un formulario php
Hola todos, soy nuevo trabajando con php y estoy trabajando en un formulario y encontré que que puedo validar el emial en php, el problema es que no se como pegar el código en mi formulario php, mi formulario tiene este codigo:

<?php

$nombre = $_POST['nombre'];
$apellido = $_POST['apellido'];
$mail = $_POST['mail'];
$empresa = $_POST['empresa'];
$area = $_POST['area'];
$mensaje = $_POST['mensaje'];

$header = 'From: ' . $mail . " ";
$header .= "X-Mailer: PHP/" . phpversion() . " ";
$header .= "Mime-Version: 1.0 ";
$header .= "Content-Type: text/plain";

$mensaje = "Este mensaje fue enviado por " . $nombre ." ". $apellido . ", de la empresa " . $empresa . " ";
$mensaje .= "Su e-mail es: " . $mail . " ";
$mensaje .= "solicitando informacion sobre: " . $area . " ";
$mensaje .= "Mensaje: " . $_POST['mensaje'] . " ";
$mensaje .= "Enviado el " . date('d/m/Y', time());

$para = 'info@prueba.com';
$asunto = 'Contacto desde la web';

mail($para, $asunto, utf8_decode($mensaje), $header);

echo 'Su Mensaje fue enviado éxitosamente, Gracias por contactarnos.';
?>

espero su valiosa ayuda,

saludos

Nepol

29/9/2009
La de Moz es la mejor hasta ahora
Como dice Saúl la de moz deja el errores como estos cuando hay subdominios:

@_subdomain.domain.com

Pero quitandole el + al @ no veo otros problemas hasta ahora.

Saúl tu expersión infalible tiene el error gravísimo de no validar el dominio para este error:

whatever@domain

Por ahora me quedo con "^[_a-zA-Z0-9-]+(.[_a-zA-Z0-9-]+)*@([_a-zA-Z0-9-]+.)*[a-zA-Z0-9-]{2,200}.[a-zA-Z]{2,6}$" de Moz
Saludos.

JulioGastelum

01/10/2009
Quiero que mis Campos sean Obligatorios
Tengo algo parecido. este es mi scrip

<?
$srv="localhost"; //server mysql
$bdname="usuarios"; // nombre bd
$bduser="root"; // user mysql
$bdpass="root"; //contraseña del user mysql
//primero comprobamos que no exista el usuario.
$nick = $_POST['nick'];
$pass2 = $_POST['pass1'];
$pass1 = $_POST['pass2'];
$email = $_POST['email'];
$name = $_POST['nombre'];
$ssql="SELECT * FROM usuarios WHERE nick='" . $nick . "'";
$link=mysql_connect($srv,$bduser,$bdpass);
$result=mysql_db_query($bdname,$ssql,$link);
if(mysql_num_rows($result)){
header("Location: capacitacion.html");
exit;
} else {
mysql_free_result($result);
//procedimos a comprobar contraseñas
if($pass1!=$pass2) {
header("Location: calendario.html");
exit;
} else {
$ssql="INSERT INTO usuarios (nick, nombre, password, email) VALUES ('$nick','$name','$pass1','$email')";
if(mysql_db_query($bdname,$ssql,$link)){
header("Location: capacitacion.html");
exit;
} else {
header("Location: capacitacion.html");
exit;
}
}
}
?>
<html>
<head>
<meta http-equiv="refresh" content="5;url=index.html"
</body>
</html>

Funciona perfecto, pero pueden dejar campos vacios y de todas formas ingresan, lo que quiero es que sean obligatorios para que me queden registrados en mi BD.
Gracias por su atencion y ayuda.

Chiquito

28/1/2010
Sobre lo de Iñaki
Marcha impecable lo tuyo, macho. Si averiguo lo otro te respondo al toque.
Muchas gracias!!

A.C.

21/4/2010
en php 5.3
sería

$email_filtrado_o_false = filter_var ($email_origen, FILTER_VALIDATE_EMAIL);

ya que ereg y eregi han sido "decrapeted" ;)

pepe

17/5/2010
nada
<?php
class db_conexion
{
function conectar ($bd,$host,$user,$pass)
{
$conex=mysql_connect($host,$user,$pass);
if(!$conex)
{
$error="HA FALLADO LA CONEXION";
return 0;
}
if (!@mysql_select_db($bd,$conex))
{
$error="No se puede abrir la base de datos";
return 0;
}
return $conex;
}
}
?>

Aquiles

24/6/2010
Y para saber el dominio ?
cual codigo me sirve para saber solo el dominio de un email

ASD@DFF.AR

Dominio = a DFF.AR

De antemanos gracias .. creo que salia al principio o me equivoco ? Alguien tiene una mejor opcion.

sociopartner

31/1/2011
La propuesta de SOUSA SED me ha dado resultados .....
Las validaciones que MOZ no controló acá se objetan ...

La estoy probando como sigue:

//Se verifica que el email tenga formato adhoc
$valida=false;
//Rutina
global $error_email;
$email=trim($v_email);
$email=strtolower($v_email);
$email=addslashes($v_email);
if(!$v_email){
$valida = false ;
}else{
if(!eregi("^[a-z]+[_.-]{0,1}[a-z0-9]+@[a-z0-9]+[_.-]{0,1}[a-z0-9]+.[a-z]{2,4}$", $v_email)){
$valida = true ;
}
}
//Fin rutina
if ( $valida )
{
echo "<script language=JavaScript>alert('Error: Email mal digitado.');</script>";
echo '<meta http-equiv="Refresh" content="0;URL=web6.html">';
exit;
}

Crassibz

11/4/2011
Comprobación de dominio
Para Iñaki,

la idea de comprobar si el dominio existe es buena.. pero lo haces conectando al puerto 80 y no todos los dominios validos para correo tienen habilitada una página web.

Sería mejor abrir el socket por ejemplo contra el puerto 25 (SMTP) o 110 (POP3) que sí deberían estar abiertos para un dominio con correo habilitado.

RODOLFO SEALES POSADA

05/6/2011
como seria...
hola como seria entonces la rutina si quiero comprobar que solo son numeros por el usuario, la arroba y luego solo un dominio en particular? es decir, que la forma de estructura sea xxxxxxxxxx@servidordecorreo.ext, donde x representan los 10 digitos en nuemros, no en letras, la arroba que denota que es un correo y esta a mitad de la cadena luego un servidor de correo en particular, digamos gmail y la extension de dominio, ejemplo . com, con lo cual quedaria solo valido los correos de estructura 012345678@gmail.com. Agradezco la ayuda y colaboracion.

Cristian

13/6/2011
Esto
Che la puta que te pario explicame como lo aplico en un form que estoy drogado no entiendo nada hdp!

Enrique M. Flores

02/1/2012
Donde coloco esta función?
Gracias por este código, soy muy nuevo en esto de programacion. entiendo lo de la funcion, pero ¿donde la coloco? en la página de captura?, en la de envio del correo?, en el header?

Esteban

14/4/2012
Como rayos aplico eso?
jejeje.. esta muy bueno todo pero como hago para aplicarlo?

Maxi

21/8/2012
Filter var
A partir de PHP5 se puede usar filter_var<br />
<br />
Si es un valido devuelve TRUE, sino FALSE.<br />
<br />
filter_var($email, FILTER_VALIDATE_EMAIL))

www.config.mx

16/10/2012
www.config.mx Comprueba si un correo existe o no
Este <a href="http://www.config.mx/validar-correo/">link</a> permite realizar la validación de un email.

Además de eso, te dice si existe o no existe.

https://www.config.mx/validar-email/

Anonimo

23/2/2013
Más sencillo
Todo eso se puede resumir a esto:
if($email, FILTER_VALIDATE_EMAIL)

sebaszyl

08/5/2014
Problema con la confirmación del campo email
Si alguien puede ayudar, quiero en un formulario que los dos campos del email sean iguales, y que si NO lo son, no se vaya al fichero php y se vuelva a quedar en el formulario HTML para que lo ponga correctamente. En el siguiente código, muestra que los emails escritos no son iguales, pero se va al fichero php siempre.
El código es:
<script>
function comprobarEmail(){
email = document.f1.email.value
email2 = document.f1.email2.value
var i = "1"
if (email == email2) {
i="1";
}
else
alert("Los dos emails son distintas...Vuelva a escribir los emails correctamente");
i="0";
}
</script>

</head>
<body>

<FORM ACTION="enviarmail.php" METHOD="GET" name="f1">
<div align="center">

<label for="email">Dirección de E-mail: *</label>
<input type="text" name="email" maxlength="80" size="45">


<label for="email2">Confirmación dirección de E-mail: *</label>
<input type="text" name="email2" maxlength="80" size="45">

<input type="submit" value="Enviar" onClick="comprobarEmail()">

</body>
</html>

box

17/3/2015
codigo no funciona como siempre
no sirve tu código te hace falta ver mas box

Noa Krossa

31/10/2015
Validación de email
En programación, cuando mas breve el código mejor, por lo que es mas fácil hacer esto en JavaScript con expresiones regulares

function validarEmail(valor) {
if (/^w+([.-]?w+)*@w+([.-]?w+)*(.w{2,3,4})+$/.test(valor)){
alert("La dirección de email " + valor + " es correcta.");
}else {
alert("La dirección de email es incorrecta.");
}
}

acnfreelancer

04/5/2016
En que página se coloca este código
En la página donde está el formulario o en el PHP que comprueba y envía el mensaje?

Gracias!

rachel cabrera

24/11/2016
E-mail
¿Para que me dicen que cambie mi correo electronico ?..si cuando lo voy a hacer ...¡no aparece el maldito formulario?además mi cuenta no aparece de ninguna forma....ni con los "dos pasos"...¡¡tengo cientos de contraseñas y correos electronicos que no recuerdo las fechas."y encima ¡¡¡¡TE LAS PIDEN!!!...me tienen hasta el gorro!!!1