Verificación de email en PHP
Este tutorial cubre la integración de Mailbeam en cualquier aplicación PHP, no solo en Laravel. Verás dos enfoques: con el cliente HTTP Guzzle (recomendado) y con cURL a secas (sin dependencias).
Requisitos previos
- PHP 8.1 o posterior
- Composer (opcional, para Guzzle)
- Una clave de API de Mailbeam (regístrate gratis)
Preparación
Añade tu clave de API a tu entorno:
# .env o configuración de entorno
MAILBEAM_KEY=mb_live_xxxxxxxxxxxxxxxxxxxxOpción A — Con Guzzle
composer require guzzlehttp/guzzle<?php
// src/Services/MailbeamService.php
namespace App\Services;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
class MailbeamService
{
private Client $client;
public function __construct()
{
$this->client = new Client([
'base_uri' => 'https://api.mailbeam.dev',
'timeout' => 5.0,
'headers' => [
'Authorization' => 'Bearer ' . $_ENV['MAILBEAM_KEY'],
'Content-Type' => 'application/json',
],
]);
}
/**
* Devuelve ['valid' => bool, 'score' => int, 'reason' => string|null]
* o null si hay un error de la API (quien llame debe fallar en abierto).
*/
public function verify(string $email): ?array
{
try {
$response = $this->client->post('/v1/verify', [
'json' => ['email' => $email],
]);
return json_decode($response->getBody()->getContents(), true);
} catch (RequestException $e) {
error_log('[Mailbeam] ha fallado la verificación: ' . $e->getMessage());
return null;
}
}
}Opción B — cURL a secas (sin dependencias)
<?php
function mailbeam_verify(string $email): ?array
{
$apiKey = $_ENV['MAILBEAM_KEY'] ?? '';
$payload = json_encode(['email' => $email]);
$ch = curl_init('https://api.mailbeam.dev/v1/verify');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_TIMEOUT => 5,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
]);
$body = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($error || !$body) {
error_log('[Mailbeam] error de cURL: ' . $error);
return null; // falla en abierto
}
return json_decode($body, true);
}Usar la verificación en tu registro
<?php
// signup.php
$email = trim(strtolower($_POST['email'] ?? ''));
$password = $_POST['password'] ?? '';
if (!$email || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
http_response_code(422);
echo json_encode(['error' => 'Escribe una dirección de email válida.']);
exit;
}
// Verifica con Mailbeam
$service = new MailbeamService();
$result = $service->verify($email);
$valid = $result['valid'] ?? true; // falla en abierto si $result es null
$score = $result['score'] ?? 100;
$reason = $result['reason'] ?? null;
if ($result !== null && (!$valid || $score < 60)) {
$message = match ($reason) {
'disposable_domain' => 'Usa una dirección de email permanente.',
'no_mx_records' => 'Este dominio no puede recibir correo.',
default => 'Escribe una dirección de email válida.',
};
http_response_code(422);
echo json_encode(['error' => $message, 'code' => $reason]);
exit;
}
// Continúa con la creación del usuario...
create_user($email, $password);
echo json_encode(['success' => true]);Añadir una capa de caché
<?php
function verify_with_cache(string $email, MailbeamService $service): ?array
{
$key = 'mailbeam_' . md5(strtolower(trim($email)));
// APCu (un solo servidor)
if (apcu_exists($key)) {
return apcu_fetch($key);
}
$result = $service->verify($email);
if ($result !== null) {
apcu_store($key, $result, 3600); // cachea durante 1 hora
}
return $result;
}Buenas prácticas
- Falla siempre en abierto (devuelve
nullante un error, no['valid' => false]) - Normaliza el email con
strtolower(trim($email))antes de verificar y de cachear - Usa
FILTER_VALIDATE_EMAILantes de llamar a Mailbeam para cazar barato los errores de sintaxis obvios - Pon un tiempo de espera de 5 segundos en la petición HTTP