WordPress y núcleo de PHP
La is_email()
función Fuente es una implementación típica de WordPress y no funciona completamente con lo que permite el RFC 6531 . Una razón podría ser que la FILTER_VALIDATE_EMAIL
constante de PHP predeterminada filter_var()
no es mucho mejor para validar algo de acuerdo con las pautas del Grupo de trabajo de ingeniería de Internet (IETF®) .
Normas
El punto es que el RFC 6531 permite "caracteres Unicode más allá del rango ASCII" . Es decir, esos son (para la parte local, antes de @
):
- Letras inglesas en mayúsculas y minúsculas (a – z, A – Z) (ASCII: 65–90, 97–122)
- Dígitos
0
a 9
(ASCII: 48–57)
- Estos personajes especiales:
! # $ % & ' * + - / = ? ^ _ ` { | } ~
- Carácter
.
(punto, punto, punto final) (ASCII: 46) siempre que no sea el primer o el último carácter, y siempre que no aparezca consecutivamente (por ejemplo, John..Doe@example.com
no está permitido).
- Se permiten caracteres especiales con restricciones. Son:
- Espacio y
"(),:;<>@[\]
(ASCII: 32, 34, 40, 41, 44, 58, 59, 60, 62, 64, 91–93)
- Las restricciones para los caracteres especiales son que solo deben usarse cuando están entre comillas, y que 2 de ellas (la barra invertida \ y la comilla "(ASCII: 92, 34)) también deben ir precedidas de una barra invertida
\
(por ejemplo, "\\"
y "\""
) .
- Se permiten comentarios con paréntesis en cada extremo de la parte local; por ejemplo,
john.smith(comment)@example.com
y (comment)john.smith@example.com
son equivalentes a "john.smith@example.com"
, pero john.(comment)smith@example.com
serían inválidos.
- Los caracteres internacionales anteriores
U+007F
, codificados como UTF-8, están permitidos por RFC 6531, aunque los sistemas de correo pueden restringir qué caracteres usar al asignar partes locales.
y para la parte global / dominio:
La parte del nombre de dominio de una dirección de correo electrónico debe cumplir con pautas estrictas: debe coincidir con los requisitos para un nombre de host, que consta de letras, dígitos, guiones y puntos. Además, la parte del dominio puede ser un literal de dirección IP, rodeado de corchetes, como jsmith@[192.168.2.1]
o jsmith@[IPv6:2001:db8::1]
[…]
Fuente: Wikipedia
¿Qué es válido?
Esto puede conducir a direcciones de correo electrónico extrañas pero válidas como las siguientes:
localpart.ending.with.dot.@example.com
(comment)localpart@example.com
"this is v@lid!"@example.com
"much.more unusual"@example.com
postbox@com
admin@mailserver1
"()<>[]:,;\\@\"\\\\!#$%&\'*+-/=?^_`{}| ~.a"@example.org
" "@example.org
Fuente: php.net / author gt@kani.hu - ejemplo arreglado por el autor de esta publicación
Límites
También hay límites de longitud locales y de dominio:
El formato de las direcciones de correo electrónico es local-part@domain
donde la parte local puede tener hasta 64 caracteres y el nombre de dominio puede tener un máximo de 253 caracteres , pero la longitud máxima de 256 caracteres de una ruta de reenvío o reversa restringe toda la dirección de correo electrónico a no debe tener más de 254 caracteres de longitud . [2] Las definiciones formales se encuentran en RFC 5322 (secciones 3.2.3 y 3.4.1) y RFC 5321, con una forma más legible en el RFC 3696 informativo [3] y las erratas asociadas .
Fuente: Wikipedia
Restricciones de WordPress
Y esto es lo que WordPress busca:
- Pruebe la longitud mínima que puede tener el correo electrónico:
strlen( $email ) < 3
- Prueba un carácter @ después de la primera posición:
strpos( $email, '@', 1 ) === false
- Prueba de caracteres no válidos:
!preg_match( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', $local )
- Prueba de secuencias de períodos:
preg_match( '/\.{2,}/', $domain )
- Prueba de períodos iniciales y finales y espacios en blanco:
trim( $domain, " \t\n\r\0\x0B." ) !== $domain
- Suponga que el dominio tendrá al menos dos subs:
$subs = explode( '.', $domain );
y luego
2 > count( $subs )
trim( $sub, " \t\n\r\0\x0B-" ) !== $sub
!preg_match('/^[a-z0-9-]+$/i', $sub )
Fuente: WP Core v4.0
Filtros y validación personalizada
Todos los casos mencionados anteriormente se activarán is_email()
para devolver falso. El resultado es filtrable (se puede adjuntar una devolución de llamada) y el filtro tendrá tres argumentos, donde el último argumento es el motivo. Ejemplo:
return apply_filters( 'is_email', false, $email, 'sub_hyphen_limits' );
lo que significa que puede anular los resultados devueltos por verificaciones específicas.
Esto le permite agregar controles especiales, por ejemplo, para permitir dominios Umlaut, partes de dominio solo para TLD, etc.
Conclusión
WordPress es seguro para la mayoría de los casos, pero más restrictivo ya que los servidores de correo deben ser compatibles con RFC. Tenga en cuenta que no todos los servidores de correo se alinearán con las pautas de RF 6531.
Editar
Dato curioso: dentro hay dos funciones relacionadas ~/wp-includes/formatting
: is_email()
y sanitize_email()
. Son prácticamente la misma función. No tengo idea de por qué alguien decidió que sería una buena idea copiar los contenidos de la función de uno a otro en lugar de simplemente agregar uno como devolución de llamada a los filtros que proporciona el otro. Como desde la v0.71 y desde la v1.5 son iguales, personalmente usaría la última cuando obtenga una cadena limpia. Tenga en cuenta que incluso afirma que no es compatible con RFC.is_email()
sanitize_email()
is_email()