
php

January 8, 2023
Validación de datos del formulario usando PHP y AJAX
En este parte del artículo, describiremos cómo implementar la validación de datos del formulario mediante el uso de expresiones regulares en PHP sin actualizar la página web usando Ajax.Veremos cómo funciona AJAX en JavaScript estándar.
Parte I: Plantilla de formulario de contacto.
Parte II: Integre Google reCAPTCHA en el formulario de contacto.
Parte III: Validación de datos del formulario usando PHP y Ajax.
El concepto de AJAX ha existido desde mediados de los años 90. Sin embargo, obtuvo un mayor reconocimiento en 2004. Hoy en día, se usa ampliamente en varias aplicaciones web para agilizar el proceso de comunicación del servidor.
AJAX significa JavaScript asíncrono y XML (Asynchronous JavaScript and XML). Es un conjunto de técnicas de desarrollo web que permiten obtener contenido del servidor back-end de forma asíncrona, sin actualizar la página. Así, permite actualizar el contenido de una página web sin recargarla.
Usando Objetos FormData
Los objetos FormData le permiten compilar un conjunto de pares clave/valor Donde la clave es el "name" del campo de formulario y el valor es su propiedad "value" para enviar mediante XMLHttpRequest.
Están destinados principalmente para el envío de los datos del formulario, pero se pueden utilizar de forma independiente con el fin de transmitir los datos tecleados.
Los datos transmitidos estarán en el mismo formato que usa el método submit() del formulario para enviar los datos si el tipo de codificación del formulario se establece en "multipart/form-data".
¡Aprenda más sobre cómo usar los objetos FormData!
Creamos objetos FormData y después añadiendo campos a la instancia usando método append().
var form_element = document.getElementsByClassName('form_data');
var form_data = new FormData();
for(var count = 0; count < form_element.length; count++) {
form_data.append(form_element[count].name, form_element[count].value);
form_data.append('g-recaptcha-response', grecaptcha.getResponse());
}
Este ejemplo construye una instancia de FormData, que almacenará los valores de todos los campos de formulario, que tienen class="form_data" y g-recaptcha-response.
Esto le permite de enviar los datos para incluir información adicional que no necesariamente debiera ser editable por el usuario en el formulario.
Luego usamos el método de envío XMLHttpRequest() para enviar los datos.
var xhr = new XMLHttpRequest();
xhr.open('POST', 'send_message.php');
xhr.send(form_data);
Hasta este punto, el proceso está incompleto: Enviamos la petición pero no sabemos en qué momento ha terminado de procesarse, ni cuál es la información que el servidor ha devuelto.
XMLHttpRequest
XMLHttpRequest es un objeto JavaScript que fue diseñado por Microsoft y adoptado por Mozilla, Apple y Google. Actualmente es un estándar de la W3C. Proporciona una forma fácil de obtener información de una URL sin tener que recargar la página completa.
¡Aprenda más sobre cómo usar XMLHttpRequest!
Para enviar una petición HTTP, creamos un objeto XMLHttpRequest, abrimos la URL y enviamos la petición. Una vez completada la transacción, el objeto contendrá información útil, como el cuerpo de la respuesta y el estado HTTP del resultado.
Una petición realizada a través de XMLHttpRequest puede obtener los datos de dos maneras, de forma asíncrona o sincrónica. Si en el método abierto el tercer parámetro async se establece en false, la petición se realiza de forma síncrona. Si este argumento es true o no se especifica XMLHttpRequest, se procesa de forma asíncrona.
Las peticiones asíncronas en el navegador se realizan con la función XMLHttpRequest, la cual permite realizar peticiones de tipo GET (obtener información), POST (enviar información), y tienen sus propios eventos: abort, error, load, loadend, loadstart, progress, timeout y readystatechange.
Onreadystatechange contiene el manejador del evento que es invocado cuando se dispara el evento readystatechange, lo cual sucede cada vez que cambia el valor de la propiedad readyState de XMLHttpRequest . La retrollamada (callback) es invocada desde el hilo perteneciente a la interfaz de usuario.
readyState, el valor de esa propiedad cambia durante el ciclo de vida de la petición. Puede contener uno de cuatro valores: OPENED, HEADERS_RECEIVED, LOADING, y DONE.
if(xhr.readyState == 4 && xhr.status == 200) {
var response = JSON.parse(xhr.responseText);
console.log(response);
}
En esa función, verificamos si el valor de readyState es igual a 4, lo que significa que la petición se completó y obtuvimos una respuesta del servidor. A continuación, verificamos si el código de status es igual a 200, lo que significa que la petición fue exitosa.
En el ejemplo vemos, que las respuestas vienen en forma de texto, pero con un formato que nos recuerda a objetos u arreglos en JavaScript. Este formato se llama JSON (JavaScript Object Notation), y permite enviar y recibir información de una manera simple y liviana.
Para poder leer este formato utilizamos el método JSON.parse, el cual es nativo en todos los navegadores, y en Internet Explorer 9 y superiores.
Pongámoslo todo junto, primero cree un nuevo archivo ajax.js y luego use el siguiente código.
function send_data() {
var form_element = document.getElementsByClassName('form_data');
var form_data = new FormData();
var xhr;
try {
// Firefox, Opera 8.0+, Safari
xhr = new XMLHttpRequest();
} catch (e) {
// Internet Explorer
try {
xhr = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
alert("¡Tu navegador no es compatible con AJAX!");
return false;
}
}
}
for(var count = 0; count < form_element.length; count++) {
form_data.append(form_element[count].name, form_element[count].value);
form_data.append('g-recaptcha-response', grecaptcha.getResponse());
}
document.getElementById('submit').disabled = true;
xhr.open('POST', 'send_message.php');
xhr.send(form_data);
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
document.getElementById('submit').disabled = false;
var response = JSON.parse(xhr.responseText);
console.log(response);
if(response.success != '') {
form_data.append('g-recaptcha-response', grecaptcha.reset());
document.getElementById('send_message').reset();
document.getElementById('information').innerHTML = response.success;
setTimeout(function(){
document.getElementById('information').innerHTML = '';
}, 9000);
document.getElementById('username_error').innerHTML = '';
document.getElementById('surname_error').innerHTML = '';
document.getElementById('email_error').innerHTML = '';
document.getElementById('phone_error').innerHTML = '';
document.getElementById('subject_error').innerHTML = '';
document.getElementById('message_error').innerHTML = '';
document.getElementById('country_error').innerHTML = '';
document.getElementById('recaptcha_error').innerHTML = '';
} else {
//display validation error
document.getElementById('username_error').innerHTML = response.username_error;
document.getElementById('surname_error').innerHTML = response.surname_error;
document.getElementById('email_error').innerHTML = response.email_error;
document.getElementById('phone_error').innerHTML = response.phone_error;
document.getElementById('subject_error').innerHTML = response.subject_error;
document.getElementById('message_error').innerHTML = response.message_error;
document.getElementById('country_error').innerHTML = response.country_error;
document.getElementById('recaptcha_error').innerHTML = response.recaptcha_error;
form_data.append('g-recaptcha-response', grecaptcha.reset());
}
if(response.error != '') {
document.getElementById('information').innerHTML = response.error;
setTimeout(function(){
document.getElementById('information').innerHTML = '';
}, 9000);
}
}
}
}
Ahora agregamos el archivo ajax.js justo antes de la etiqueta del cuerpo de cierre (</body>):
<!-- Send message -->
<script src="js/ajax.js"></script>
Validación de datos de formularios mediante el uso de expresiones regulares en PHP
Las expresiones regulares son un mecanismo muy potente empleado en programación formado por un conjunto de carácteres y metacarácteres que nos permite definir patrones para realizar busquedas en una cadena o validar sus datos, por ejemplo, las podemos utilizar para validar los datos enviados por un usuario en un formulario web.
El procesamiento de una expresión regular puede llegar a ser costoso y muy complicado, tanto que algunos programadores evitan usar este mecanismo de programación, aunque por otra parte, es una herramienta que nos puede ayudar a ahorrar mucho tiempo a la hora de resolver un problema.
Las expresiones regulares van encerradas en delimitadores, que son cualquier par de caracteres no alfanuméricos (excepto la barra invertida \ y el espacio en blanco). Los delimitadores más utilizados son las barras oblícuas (/), aunque también se pueden utilizar almohadillas #, virgulillas ~... Además de (), [], {}, o <>.
Expresión regular que identifica el nombre entre 3 a 30 caracteres:
if(!preg_match("/^[a-zA-ZáéíóúÁÉÍÓÚäëïÑñöüÄËÏÖÜàèìòùÀÈÌÒÙ]{3,30}$/", $username)) {
$username_error = 'Solo se permiten letras y de 3 a 30 caracteres.';
}
En el ejemplo anterior, usamos la función preg_match, que realiza una coincidencia de expresión regular.
Empezamos diciendole al analizador sintáctico que encuentre el principio de la cadena (^), seguido de cualquier caracteres mayúsculas y minúsculas incluso los caracteres no incluidos en el idioma inglés (a-zA-ZáéíóúÁÉÍÓÚäëïÑñöüÄËÏÖÜàèìòùÀÈÌÒÙ).
A continuación entre llaves (3,30) se asegura que sean al menos 3 de esos caracteres, pero no más de 30. Por último, el final de la cadena ($).
Expresión regular que identifica un número de teléfono movil de 9 digitos:
if(!preg_match("/^[0-9]{9}$/", $phone)) {
$phone_error = 'Solo se permiten números móviles de 9 dígitos.';
}
En el ejemplo anterior indicamos cualquier dígito del 0 al 9 con los corchetes, seguidamente indicamos que el patrón debe repetirse 9 veces con las llaves, las llaves y los corchetes son metacarácteres que indican a PHP un comportamiento específico en el patrón.
Una de las labores más comunes en nuestra vida como desarrolladores es validar una dirección de correo electrónico. Existen múltiples formas de realizar ésta tarea desde expresiones regulares a funciones propias de PHP.
El siguiente código muestra el uso de una expresión regular para validar una dirección de correo electrónico:
if(!preg_match("/^[a-z0-9_-]+(?:\.[a-z0-9_-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/", $email)) {
$email_error = 'El formato de la dirección de correo no es válido.';
}
Otra opción, tal vez la mas sencilla que proporciona PHP, es la función filter_var(), que filtra una variable según el tipo de filtro aplicado, eliminando aquellos caracteres no validos o validando.
El siguiente código muestra un ejemplo sencillo del uso de la función filter_var():
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$email_error = 'El formato de la dirección de correo no es válido.';
}
En el ejemplo anterior, usamos filter_var, esta función desinfecta y filtra los datos almacenados en la variable. Acepta dos parámetros. El primer parámetro es la variable sobre la que desea aplicar el filtro. El segundo parámetro es el tipo de filtro a aplicar a la variable.
Aquí puede leer más sobre la función filter_var.
En nuestro formulario queremos limitar tanto el número de carácteres permitido, como el conjunto de carácteres de contenido del texto.
if(!preg_match("/^[A-Za-z0-9-\s_'.,¿?ąćęłńśóżźĄĆĘŁŃŚÓŻŹáéíóúÁÉÍÓÚäëïÑñöüÄËÏÖÜàèìòùÀÈÌÒÙ]{60,1200}$/", $message)) {
$message_error = 'Mensaje demasiado corto (se permiten de 60 a 1200 caracteres).';
}
El ejemplo anterior, nos permite usar caracteres en mayúsculas y minúsculas, incluso los caracteres no incluidos en el idioma inglés, números, espacios en blanco, puntos, comas y los signos de interrogación (¿ ?) y limitamos la longitud del mensaje de 60 a 1200 caracteres.
Las excepciones son una forma eficiente de detener una función sin producir resultados incorrectos al final. Si en algún momento necesitas probar tus expresiones regulares puedes utilizar la siguiente herramienta regex101.com
Integrando Google ReCaptcha en PHP
Parte anterior aprendimos cómo crear fácilmente Google reCAPTCHA e integrarlo con el formulario de contacto, pero todavía no estaría funcionando, falta la parte PHP que le haga cumplir con su función.
Para completar el proceso es necesario verificar que los datos enviados desde el formulario son validos. Para ello utilizaremos el API de reCAPTCHA donde se deben enviar vía POST
Comprobando el estado del elemento reCAPTCHA
// Clave secreta de la API de Google reCAPTCHA
$secret_key = 'TU CLAVE SECRETA AQUÍ';
$ip = $_SERVER["REMOTE_ADDR"];
$googleRecaptchaResponse = $_POST['g-recaptcha-response'];
// Verificación de respuesta reCAPTCHA
$url = 'https://www.google.com/recaptcha/api/siteverify?secret='. urlencode($secret_key).'&response='. urlencode($googleRecaptchaResponse).'&remoteip='. $ip;
$verify_captcha = file_get_contents($url);
// Decodificar la respuesta reCAPTCHA
$verify_response = json_decode($verify_captcha);
// Compruebe si la respuesta de reCAPTCHA devuelve el éxito
if(!$verify_response->success == true) {
$recaptcha_error = "Verificación reCaptcha no completada!";
}
Con pocos pasos es posible integrar de manera sencilla reCAPTCHA y así reducir la cantidad de contenido malicioso por parte de spammers o robots automatizados. Es necesario hacer la validación a nivel de frontend y backend para que la protección sea la adecuada.
Envío de correo a través de la función mail()
Los sitios web creados en PHP pueden aprovechar la función mail(), que crea la capacidad de enviar correos directamente desde sitio web.
La función mail() es más sencilla y es muy bien conocida por su simplicidad de uso: especificas a quién enviar, el asunto, el mensaje y ¡Listo!.
Cuando enviamos un email usando la función mail() nos lo envía en texto plano. Para poder enviar email con formato HTML debemos incluir en la cabecera que el contenido que estamos enviando es un contenido HTML.
Enviar email con formato HTML usando funcion mail()
// Creamos una matriz de datos recibidos del formulario
$message_data = array(
'sent_at' => $sent_at,
'username' => $username,
'surname' => $surname,
'phone' => $phone,
'email' => $email,
'country' => $country,
'subject' => $subject,
'message' => $message,
'website' => $website
);
// Preparación de contenido para ser enviado como HTML
$template = file_get_contents("template.html");
foreach($message_data as $key => $value) {
$template = str_replace('{{ '.$key.' }}',$value, $template);
}
// Aquí es donde insertas la dirección de correo electrónico de tu destinatario.
$to = "DIRECCIÓN DE CORREO ELECTRÓNICO DEL DESTINATARIO";
// Para enviar correo HTML, se debe establecer el encabezado de tipo de contenido
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type: text/html; charset=utf-8" . "\r\n";
// Encabezados adicionales
$headers .= "To:" . $to . "\r\n";
$headers .= "From:" . $email . "\r\n";
$headers .= "Subject:" . $subject . "\r\n";
$headers .= "X-Mailer: PHP/".phpversion();
if(mail($to, $subject, $template, $headers)) {
$success = '<div class="alert alert-success">Gracias, por el mensaje, me pondré en contacto con usted en breve.</div>';
} else {
$error = '<div class="alert alert-danger">El mensaje no se pudo enviar. Por favor, inténtelo de nuevo más tarde</div>';
}
Si revisaste todo el código, notarás que estamos enviando un mensaje HTML en que cargará tu contenido desde el archivo template.html.
Este formato ofrece una mayor funcionalidad en comparación con los mensajes de texto sin formato, ya que HTML es altamente personalizable. Puedes cambiar el color, el estilo, la imagen o incluso incluir archivos multimedia que generalmente son obsoletos en un correo electrónico de texto sin formato.
Crea un nuevo archivo y lo llamamos template.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Correo electrónico de {{ username }}</title>
</head>
<body style="margin: 0; padding: 0; font-family:Varela Round, Trebuchet MS, Helvetica, sans-serif;">
<table style="vertical-align: top; min-width: 320px; border-spacing: 0; border-collapse: collapse; background-color: #ffffff; width: 100%;">
<tbody>
<tr>
<td>
<table style="vertical-align: top; border-spacing: 0; border-collapse: collapse; padding: 25px 0 25px 0; width: 100%;">
<tbody>
<tr>
<td>
<div style="background-color:#ffffff; color: #022A3F;">
<div style="min-width: 320px; max-width: 600px; margin: 0 auto; background-color: transparent; padding: 0 15px 0 15px;">
<div style="border-collapse: collapse;display: table; width:100%;">
<table style="vertical-align: top; border-spacing: 0; border-collapse: collapse; padding: 25px 0 25px 0; width: 100%;">
<tbody>
<tr>
<td style="width: 100%; padding: 0;">
<table style="border-spacing: 0; border-collapse: collapse; width: 100%; text-align: center; margin: 15px 0 30px 0;">
<tbody>
<tr>
<td style="text-align: left;">
<span style="text-align: left; padding: 4px; font-size: 12px; padding-left:0; color:#333333;">
{{ country }}
</span>
</td>
<td style="text-align: right;">
<span style="text-align: right; padding: 4px; font-size: 12px; padding-right:0; color:#333333;">
{{ sent_at }}
</span>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<table style="width: auto; margin: 0 20px 0 20px; text-align: center; color: #022A3F; padding: 10px 0 10px 10px;">
<tbody>
<tr>
<td style="text-align: left; width: 85px; height:45px;">
<span style="font-size: 14px; font-weight:600;">
Mensaje de:
</span>
</td>
<td style="text-align: left;">
<span style="font-size: 13px;">
{{ username }} {{ surname }}
</span>
</td>
</tr>
<tr>
<td style="text-align: left; height:45px;">
<span style="font-size: 14px; font-weight:600;">
Pais:
</span>
</td>
<td style="text-align: left;">
<span style="font-size: 13px;">
{{ country }}
</span>
</td>
</tr>
<tr>
<td style="text-align: left; height:45px;">
<span style="font-size: 14px; font-weight:600;">
E-mail:
</span>
</td>
<td style="text-align: left;">
<span style="font-size: 13px;">
{{ email }}
</span>
</td>
</tr>
<tr>
<td style="text-align: left; height:45px;">
<span style="font-size: 14px; font-weight:600;">
Teléfono:
</span>
</td>
<td style="text-align: left;">
<span style="font-size: 13px;">
{{ phone }}
</span>
</td>
</tr>
<tr>
<td style="text-align: left; vertical-align: top; height:45px;">
<span style="font-size: 14px; font-weight:600;">
Asunto:
</span>
</td>
<td style="text-align: left; vertical-align: top;">
<span style="font-size: 13px;">
{{ subject }}
</span>
</td>
</tr>
<tr>
<td style="text-align: left; vertical-align: top; height:45px;">
<span style="font-size: 14px; font-weight:600;">
Mensaje:
</span>
</td>
<td style="text-align: left; vertical-align: top; ">
<p style="font-size: 13px; text-align: left; line-height: 1.5; word-spacing: 1px; padding: 0 0 30px 0;">
{{ message }}
</p>
</td>
</tr>
</tbody>
</table>
<table style="border-spacing: 1px; border-top: 1px solid #ddd7d7;width: 80%; margin: 0 20px 0 40px;">
<tbody>
<tr>
<td></td>
</tr>
</tbody>
</table>
<div style="padding:10px 25px 10px 25px;">
<div style="text-align: center; font-size: 14px; line-height: 1.5; color: #228896; font-family: Varela Round, Trebuchet MS, Helvetica, sans-serif;">
<p style="margin:0; margin-top: 5px;">
<strong>
Saludos,
</strong>
</p>
<p style="margin:0;">
{{ website }}
</p>
</div>
</div>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
Es importante indicar que la función mail() no es conveniente para grandes volúmenes de correo en bucle. Esta función abre y cierra un socket SMTP para cada correo, algo que no es muy eficiente.
Puedes leer más sobre la función mail() en el sitio web de PHP
Envío de correo usando la biblioteca de Swift Mailer
La biblioteca Swift Mailer nos facilitó el envío de correos electrónicos tanto en texto plano, como empleando HTML. Es una biblioteca que cubre casi todos los aspectos del envío de correos electrónicos, desde la configuración de diferentes transportes hasta la personalización del mensaje que se envía.
Symfony lo usa como componente por defecto, su integración con sistemas como Gmail o servidores SMTP era prácticamente inmediata, por lo que casi todos los proyectos basados en Symfony lo empleen para gestionar el envío de correos electrónicos.
Su repositorio en GitHub https://github.com/swiftmailer/swiftmailer
Lo instalamos via composer o clonamos con git.
Instalación via composer:
composer require swiftmailer/swiftmailer
clonando con git:
git clone https://github.com/swiftmailer/swiftmailer.git
Después de que se complete la instalación de la biblioteca de Swift Mailer con las dependencias necesarias en el directorio de proveedores. Se creará un nuevo archivo composer.json, debería verse así:
{
"require": {
"swiftmailer/swiftmailer": "^6.0"
}
}
Usar la biblioteca Swift Mailer es realmente muy simple, todo lo que tiene que hacer es incluir el archivo autoload.php creado por Composer en nuestro código, como se muestra en el siguiente fragmento:
<?php
//Agregar la biblioteca Swiftmailer.
require_once ('../vendor/autoload.php');
// Establecer texto en formato html
$html_content = '<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Correo electrónico de '. $username .'</title>
</head>
<body style="margin: 0; padding: 0; font-family:Varela Round, Trebuchet MS, Helvetica, sans-serif;">
<table style="vertical-align: top; border-spacing: 0; border-collapse: collapse; padding: 25px; width: 100%;">
<tbody>
<tr>
<td style="text-align: left;">
<span style="text-align: left; padding: 4px; font-size: 12px; padding-left:0; color:#333333;">
'. $country .'
</span>
</td>
<td style="text-align: right;">
<span style="text-align: right; padding: 4px; font-size: 12px; padding-right:0; color:#333333;">
'. $sent_at .'
</span>
</td>
</tr>
<tr>
<td style="text-align: left; width: 85px; height:45px;">
<span style="font-size: 14px; font-weight:600;">
Mensaje de:
</span>
</td>
<td style="text-align: left;">
<span style="font-size: 13px;">
'. $username .' '. $surname .'
</span>
</td>
</tr>
<tr>
<td style="text-align: left; height:45px;">
<span style="font-size: 14px; font-weight:600;">
Pais:
</span>
</td>
<td style="text-align: left;">
<span style="font-size: 13px;">
'. $country .'
</span>
</td>
</tr>
<tr>
<td style="text-align: left; height:45px;">
<span style="font-size: 14px; font-weight:600;">
E-mail:
</span>
</td>
<td style="text-align: left;">
<span style="font-size: 13px;">
'. $email .'
</span>
</td>
</tr>
<tr>
<td style="text-align: left; height:45px;">
<span style="font-size: 14px; font-weight:600;">
Teléfono:
</span>
</td>
<td style="text-align: left;">
<span style="font-size: 13px;">
'. $phone .'
</span>
</td>
</tr>
<tr>
<td style="text-align: left; vertical-align: top; height:45px;">
<span style="font-size: 14px; font-weight:600;">
Asunto:
</span>
</td>
<td style="text-align: left; vertical-align: top;">
<span style="font-size: 13px;">
'. $subject .'
</span>
</td>
</tr>
<tr>
<td style="text-align: left; vertical-align: top; height:45px;">
<span style="font-size: 14px; font-weight:600;">
Mensaje:
</span>
</td>
<td style="text-align: left; vertical-align: top; ">
<p style="font-size: 13px; text-align: left; line-height: 1.5; word-spacing: 1px; padding: 0 0 30px 0;">
'. $message .'
</p>
</td>
</tr>
</tbody>
</table>
</body>
</html>';
// Establecer texto sin formato
$plain_text = "Asunto: $subject \r\n Correo electrónico: $email \r\n Nombre: $username \r\n Apellido: $surname \r\n Número de teléfono: $phone \r\n País: $country \r\n Mensaje:\r\n $message \r\n";
// Configuración del servidor SMTP
$smtp_server = 'DIRECCIÓN DEL SERVIDOR DE CORREO';
$smtp_username = 'NOMBRE DE USUARIO DE CORREO';
$smtp_password = 'CONTRASEÑA DE USUARIO DE CORREO';
$smtp_port = 'PUERTO DE SERVIDOR DE CORREO';
$smtp_encryption = 'CIFRADO DEL SERVIDOR DE CORREO';
// Crear transporte SMTP
$transport = new Swift_SmtpTransport($smtp_server, $smtp_port, $smtp_encryption);
$transport->setUsername($smtp_username)->setPassword($smtp_password);
// Creando mensaje
$send_message = new Swift_Message();
$send_message->setSubject($subject)
->setFrom([$email => $username . ' ' . $surname])
->setTo(['DIRECCIÓN DE CORREO ELECTRÓNICO DEL DESTINATARIO' => 'NOMBRE DEL DESTINATARIO'])
->setBody($html_content, 'text/html')
->addPart($plain_text, 'text/plain');
// Transferir transporte a Swift Mailer
$mailer = new Swift_Mailer($transport);
// Enviando mensaje
$result = $mailer->send($send_message);
if($result) {
$success = '<div class="alert alert-success">Gracias, por el mensaje, me pondré en contacto con usted en breve.</div>';
} else {
$error = '<div class="alert alert-danger">El mensaje no se pudo enviar. Por favor, inténtelo de nuevo más tarde</div>';
}
?>
La biblioteca de Swift Mailer admite diferentes transportes como SMTP y Sendmail mientras envía un correo electrónico. Entonces, lo primero que debe hacer es inicializar el objeto transport.
Swift Mailer es probablemente una de las mejores librerías para enviar correos mediante SMTP y sendmail que existe en estos momentos para PHP. Para obtener información más detallada, asegúrate de consultar la página del proyecto Swift Mailer.
Symfony está completamente integrado con Swift Mailer, una librería muy completa para el envío de emails. Para obtener información más detallada, asegúrate de consultar la página del proyecto Symfony.
Ahora estás familiarizado con la función de envío de correo electrónico de PHP y cómo usar Swift Mailer para enviar correos electrónicos.
Pongámoslo todo junto, primero cree un nuevo archivo send_message.php y luego use el siguiente código:
<?php
// Agregar la biblioteca Swiftmailer.
require_once ('../vendor/autoload.php');
// Clave secreta de la API de Google reCAPTCHA
$secret_key = 'TU CLAVE SECRETA AQUÍ';
// Formato de fecha
$sent_at = date("j F Y ");
// Dirección de IP
$ip = $_SERVER["REMOTE_ADDR"];
// Nombre del Host
$website = $_SERVER["HTTP_HOST"];
if(isset($_POST["fusername"]) && $_SERVER["REQUEST_METHOD"] == "POST")
{
sleep(2);
$success = '';
$username = $_POST['fusername'];
$surname = $_POST['fsurname'];
$phone = $_POST['fphone'];
$email = $_POST['femail'];
$country = $_POST['fcountry'];
$subject = $_POST['fsubject'];
$message = $_POST['fmessage'];
$googleRecaptchaResponse = $_POST['g-recaptcha-response'];
$username_error = '';
$surname_error = '';
$email_error = '';
$phone_error = '';
$subject_error = '';
$message_error = '';
$country_error = '';
$recaptcha_error = '';
$error = '';
$pattern = "/^[a-zA-ZąćęłńśóżźĄĆĘŁŃŚÓŻŹáéíóúÁÉÍÓÚäëïÑñöüÄËÏÖÜàèìòùÀÈÌÒÙ]{3,30}$/";
$pattern_phone = "/^[0-9]{9}$/";
$pattern_email ="/^[a-z0-9_-]+(?:\.[a-z0-9_-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/";
$pattern_subject ="/^[a-zA-Z\sąćęłńśóżźĄĆĘŁŃŚÓŻŹáéíóúÁÉÍÓÚäëïÑñöüÄËÏÖÜàèìòùÀÈÌÒÙ]+$/";
$pattern_message ="/^[A-Za-z0-9-\s_'ąćęłńśóżźĄĆĘŁŃŚÓŻŹ.,¿?áéíóúÁÉÍÓÚäëïÑñöüÄËÏÖÜàèìòùÀÈÌÒÙ]{60,1200}$/";
// Validación de formulario
if(empty($username)) {
$username_error = 'Nombre no puede dejarse en blanco.';
} else {
if(!preg_match($pattern, $username)) {
$username_error = 'Solo se permiten letras y de 3 a 30 caracteres.';
}
}
if(empty($surname)) {
$surname_error = 'Apellido no puede dejarse en blanco.';
} else {
if(!preg_match($pattern, $surname)) {
$surname_error = 'Solo se permiten letras y de 3 a 30 caracteres.';
}
}
if(empty($email)) {
$email_error = 'Correo electrónico no puede estar en blanco.';
} else {
if(!preg_match($pattern_email, $email)) {
$email_error = 'El formato de la dirección de correo no es válido.';
}
}
if(empty($phone)) {
$phone_error = 'Número de teléfono no puede estar en blanco.';
} else {
if(!preg_match($pattern_phone, $phone)) {
$phone_error = 'Solo se permiten números móviles de 9 dígitos.';
}
}
if(empty($subject)) {
$subject_error = 'Asunto no puede estar en blanco.';
} else {
if(!preg_match($pattern_subject, $subject)) {
$subject_error = 'Solo se permiten letras y espacios en blanco.';
}
}
if(empty($message)) {
$message_error = 'Mensaje no puede estar en blanco.';
} else {
if(!preg_match($pattern_message, $message)) {
$message_error = 'Mensaje demasiado corto (se permiten de 60 a 1200 caracteres).';
}
}
if(empty($country)) {
$country_error = 'Por favor, seleccione un país';
}
if(empty($googleRecaptchaResponse)) {
$recaptcha_error = 'ReCaptcha no puede estar en blanco.';
} else {
// Verificación de respuesta reCAPTCHA
$url = 'https://www.google.com/recaptcha/api/siteverify?secret='. urlencode($secret_key).'&response=' . urlencode($googleRecaptchaResponse).'&remoteip='. $ip;
$verify_captcha = file_get_contents($url);
// Decodificar la respuesta reCAPTCHA
$verify_response = json_decode($verify_captcha);
// Compruebe si la respuesta de reCAPTCHA devuelve el éxito
if(!$verify_response->success == true) {
$recaptcha_error = "Verificación reCaptcha no completada!";
}
}
// Fin validación de formulario
// Si no hay errores
if($username_error == '' && $surname_error == '' && $email_error == '' && $phone_error == '' && $subject_error == '' && $message_error == '' && $recaptcha_error == '' && $country_error == '') {
// Creamos una matriz de datos recibidos del formulario
$message_data = array(
'sent_at' => $sent_at,
'username' => $username,
'surname' => $surname,
'phone' => $phone,
'email' => $email,
'country' => $country,
'subject' => $subject,
'message' => $message,
'website' => $website
);
// Preparación de contenido para ser enviado como HTML
$template = file_get_contents("template.html");
foreach($message_data as $key => $value) {
$template = str_replace('{{ '.$key.' }}',$value, $template);
}
// Aquí es donde insertas la dirección de correo electrónico de tu destinatario.
$to = "DIRECCIÓN DE CORREO ELECTRÓNICO DEL DESTINATARIO";
// Para enviar correo HTML, se debe establecer el encabezado de tipo de contenido
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type: text/html; charset=utf-8" . "\r\n";
// Encabezados adicionales
$headers .= "To:" . $to . "\r\n";
$headers .= "From:" . $email . "\r\n";
$headers .= "Subject:" . $subject . "\r\n";
$headers .= "X-Mailer: PHP/".phpversion();
if(mail($to, $subject, $template, $headers)) {
$success = '<div class="alert alert-success">Gracias, por el mensaje, me pondré en contacto con usted en breve.</div>';
} else {
$error = '<div class="alert alert-danger">El mensaje no se pudo enviar. Por favor, inténtelo de nuevo más tarde</div>';
}
}
$output = array(
'success' => $success,
'username_error' => $username_error,
'surname_error' => $surname_error,
'email_error' => $email_error,
'phone_error' => $phone_error,
'subject_error' => $subject_error,
'message_error' => $message_error,
'country_error' => $country_error,
'recaptcha_error' => $recaptcha_error,
'error' => $error
);
echo json_encode($output);
}
?>
Aprendimos cómo crear fácilmente un formulario de contacto integrado con Google reCAPTCHA. Así como también aprendimos a validar datos usando expresiones regulares sin tener que actualizar la página. Puede ver una demostración en vivo usando el enlace Demostración a continuación.