Historial del chat

ChatGPT

Photo Realistic Image GPT

Explorar GPT

Proyectos

Nuevo proyecto

Ayer

Serpiente y rana venenosa

7 días anteriores

Renovación y posibles problemas

30 días anteriores

Error en archivo ZIP

Problema con PayPal Checkout

Preguntar sobre webs

Ver planesAcceso ilimitado, características de Team y más

Ana Diaz

Abrir barra lateral

ChatGPT o3-mini-high

ChatGPT o3-mini-high

Compartir

Dijiste:

Hola chat, mira, mi hosting es shared y no me permite enviar mas de 100 emails a la hora, que pagina me podrias hacer en php para que envie 50 emails a la hora de una lista de emails en un archivo txt?

O como podria hacer?

Razonado sobre el envío de correos en PHP durante 8 segundos

Te propongo una solución en la que se envíen 50 correos cada hora mediante un script PHP que se ejecute a través de un cron job. La idea es la siguiente:

Archivo con la lista de emails:
Tendrás un archivo emails.txt en el que cada línea contiene un email.

Archivo para llevar registro:
Para evitar volver a enviar a los mismos correos, se usará otro archivo (por ejemplo, emails_sent.txt) en el que se irán registrando los emails a los que ya se envió el mensaje.

Script PHP:
El script leerá la lista completa, descartará los correos a los que ya se envió y tomará los primeros 50 que queden. A esos se les enviará el email y se irán registrando como enviados.

Cron job:
Programarás el cron para que ejecute el script cada hora. Así te aseguras de no superar el límite de envío que impone tu hosting.

A continuación, un ejemplo de código PHP que implementa esta idea:

php

Copiar

<?php
// Nombre de los archivos
$emails_file = 'emails.txt'; // Lista completa de emails (un email por línea)
$sent_file = 'emails_sent.txt'; // Emails a los que ya se les envió el mensaje

// Leer la lista completa de emails
if (!file_exists($emails_file)) {
die("El archivo $emails_file no existe.");
}
$emails = file($emails_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

// Leer los emails a los que ya se envió el mensaje
if (file_exists($sent_file)) {
$sent_emails = file($sent_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
} else {
$sent_emails = array();
}

// Calcular los emails que aún no han recibido el mensaje
$pending_emails = array_diff($emails, $sent_emails);

// Seleccionar los primeros 50 emails pendientes
$emails_to_send = array_slice($pending_emails, 0, 50);

if (empty($emails_to_send)) {
echo "No quedan emails pendientes de envío.";
exit;
}

// Configuración del email
$subject = "Asunto de tu email";
$message = "Este es el contenido de tu email.";
$headers = "From: [email-masked]\r\n" .
"Reply-To: [email-masked]\r\n" .
"X-Mailer: PHP/" . phpversion();

// Enviar cada email y registrar los que se hayan enviado
foreach ($emails_to_send as $email) {
// Puedes personalizar el mensaje o incluso validar el email antes de enviar
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
if (mail($email, $subject, $message, $headers)) {
// Registrar el email como enviado
file_put_contents($sent_file, $email . "\n", FILE_APPEND);
echo "Email enviado a: $email<br>";
} else {
echo "Error al enviar email a: $email<br>";
}
} else {
echo "Formato de email no válido: $email<br>";
}
}
?>

¿Cómo funciona este script?

Lectura de archivos:
Se lee emails.txt y se comprueba, si existe, el archivo emails_sent.txt.

Cálculo de pendientes:
Se obtiene la diferencia entre la lista completa y los ya enviados.

Selección de 50 correos:
Se toma un slice de 50 correos de la lista de pendientes.

Envío y registro:
Se envía el email a cada dirección y, si el envío es exitoso, se añade el email a emails_sent.txt.

Configurar el Cron Job

Para que se envíen 50 correos cada hora, debes configurar un cron job en tu hosting. Por ejemplo, si tu script se llama envia_emails.php y se encuentra en la ruta /home/usuario/public_html/, el cron job podría ser:

ruby

Copiar

0 * * * * /usr/bin/php /home/usuario/public_html/envia_emails.php

Con esto, cada hora (al minuto 0) se ejecutará el script y enviará hasta 50 correos.

Consideraciones adicionales

Tiempo de ejecución:
Si el envío de emails tarda más de lo esperado, asegúrate de que el tiempo máximo de ejecución de PHP (max_execution_time) sea suficiente o ejecuta el script mediante cron para evitar limitaciones de tiempo en solicitudes web.

Control de errores:
Puedes agregar más manejo de errores o logging según necesites para hacer seguimiento de los envíos.

Mejoras:
Si la lista de correos es muy grande o quieres una solución más robusta, podrías considerar usar una base de datos para llevar el control de los envíos o utilizar librerías como PHPMailer.

Con este enfoque, podrás cumplir con la restricción de tu hosting de enviar menos de 100 emails por hora, enviando solo 50 cada vez y controlando quién ya recibió el mensaje. ¡Suerte con tu proyecto!

o3-mini-high

Dijiste:

Pero como sabria el cron que emails ha enviado antes y siga con los siguientes emails?

Razonado sobre el control de emails enviados durante 4 segundos

El cron job en sí no "recuerda" qué emails ya han sido enviados; es el propio script PHP el encargado de gestionar ese seguimiento. Para lograrlo, el script utiliza un archivo (por ejemplo, emails_sent.txt) en el que se almacenan los emails a los que ya se les ha enviado el mensaje. Cada vez que se ejecuta el script, se realiza lo siguiente:

Lectura de la lista completa:
Se lee el archivo emails.txt que contiene todos los emails a los que se desea enviar el mensaje.

Lectura del registro de envíos:
Se lee el archivo emails_sent.txt, que contiene los emails que ya han sido procesados (enviados).

Cálculo de emails pendientes:
Se comparan ambas listas (la completa y la de enviados) para determinar cuáles son los emails que aún no han recibido el mensaje.

Envío de los próximos 50 emails:
Se seleccionan los primeros 50 emails de la lista pendiente y se les envía el correo. Una vez enviado cada email, se agrega a emails_sent.txt.

De esta forma, en cada ejecución del script (controlada por el cron job), el script "sabe" cuáles emails ya fueron enviados porque están registrados en emails_sent.txt y, por tanto, continúa con los siguientes emails pendientes. Así evitas enviar dos veces el mismo correo y respetas el límite de envío de tu hosting.

o3-mini-high

Dijiste:

Y no habria algo en php que hiciera lo mismo?

Razonado sobre opciones en PHP para envío de emails durante 11 segundos

PHP, por sí mismo, es un lenguaje sin estado, lo que significa que cada vez que se ejecuta un script, "no recuerda" lo que ocurrió en ejecuciones anteriores. Por ello, para lograr que el sistema "sepa" qué correos ya han sido enviados, es necesario implementar algún mecanismo de persistencia, ya sea mediante archivos (como en el ejemplo anterior) o utilizando una base de datos.

Si prefieres evitar el uso de archivos para registrar los emails enviados, puedes implementar una solución en PHP que utilice una base de datos, por ejemplo, SQLite (o MySQL si lo prefieres). De esta forma, el script se encarga de:

Almacenar la lista de emails y su estado (enviado o no).

Consultar cuáles emails aún no se han enviado.

Enviar los siguientes 50 correos y actualizar su estado en la base de datos.

A continuación, te muestro un ejemplo usando SQLite:

php

Copiar

<?php
// Configuración de la base de datos SQLite
$dbFile = 'emails.db'; // Archivo de la base de datos SQLite
try {
$db = new PDO('sqlite:' . $dbFile);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (Exception $e) {
die("Error al conectar con la base de datos: " . $e->getMessage());
}

// Crear la tabla si no existe
$db->exec("CREATE TABLE IF NOT EXISTS emails (
id INTEGER PRIMARY KEY AUTOINCREMENT,
email TEXT UNIQUE,
sent INTEGER DEFAULT 0
)");

// Importar emails del archivo emails.txt si la tabla está vacía
$result = $db->query("SELECT COUNT(*) FROM emails")->fetchColumn();
if ($result == 0) {
if (!file_exists('emails.txt')) {
die("El archivo emails.txt no existe.");
}
$emailsList = file('emails.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$stmt = $db->prepare("INSERT OR IGNORE INTO emails (email) VALUES (:email)");
foreach ($emailsList as $email) {
$stmt->execute([':email' => trim($email)]);
}
}

// Seleccionar 50 emails que aún no han sido enviados
$stmt = $db->prepare("SELECT id, email FROM emails WHERE sent = 0 LIMIT 50");
$stmt->execute();
$emailsToSend = $stmt->fetchAll(PDO::FETCH_ASSOC);

if (empty($emailsToSend)) {
echo "No quedan emails pendientes de envío.";
exit;
}

// Configuración del email
$subject = "Asunto de tu email";
$message = "Este es el contenido de tu email.";
$headers = "From: [email-masked]\r\n" .
"Reply-To: [email-masked]\r\n" .
"X-Mailer: PHP/" . phpversion();

// Preparamos la consulta para actualizar el estado de envío
$updateStmt = $db->prepare("UPDATE emails SET sent = 1 WHERE id = :id");

// Enviar los emails seleccionados
foreach ($emailsToSend as $row) {
$email = $row['email'];
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
if (mail($email, $subject, $message, $headers)) {
// Actualizar en la base de datos que el email fue enviado
$updateStmt->execute([':id' => $row['id']]);
echo "Email enviado a: $email<br>";
} else {
echo "Error al enviar email a: $email<br>";
}
} else {
echo "Formato de email no válido: $email<br>";
}
}
?>

¿Cómo funciona este script?

Conexión y configuración de la base de datos:
Se conecta a una base de datos SQLite (almacenada en el archivo emails.db) y se crea la tabla emails si aún no existe. La tabla tiene tres campos:

id: identificador único.

email: dirección de correo.

sent: bandera que indica si ya se envió el email (0 = no enviado, 1 = enviado).

Importación de emails:
Si la tabla está vacía, se importan los correos desde el archivo emails.txt. Esto asegura que sólo se carguen una vez.

Selección de emails pendientes:
Se consulta la base de datos para obtener 50 emails cuyo estado de sent sea 0 (no enviados).

Envío y actualización:
Se envía el correo a cada dirección y, si el envío es exitoso, se actualiza la columna sent a 1 en la base de datos para marcarlo como enviado.

Configuración del Cron Job

Una vez que tengas este script (por ejemplo, lo guardas como envia_emails.php), puedes configurar un cron job en tu hosting para que se ejecute cada hora:

ruby

Copiar

0 * * * * /usr/bin/php /ruta/a/tu/script/envia_emails.php

Con este método, el script mismo gestiona el registro de qué emails ya se han enviado sin necesidad de recurrir a un archivo externo adicional. Así, en cada ejecución se envían los siguientes 50 correos pendientes, respetando el límite impuesto por tu hosting.

Resumen

PHP no "recuerda" estados entre ejecuciones:
Por ello se debe utilizar un medio persistente (archivo o base de datos).

Solución en PHP con SQLite:
El ejemplo anterior muestra cómo hacerlo usando una base de datos SQLite para registrar y actualizar el estado de cada email.

Esta es una solución totalmente en PHP que cumple la función de recordar cuáles correos han sido enviados y continuar con los siguientes sin repetir envíos. ¡Espero que te sea útil!

o3-mini-high

Dijiste:

Y me darias el codigo de:
envia_emails.php

Que use un archivo:
emails.txt

para tener la relacion de emails a enviar?

En vez de hacerlo con una base de datos SQLite?

Razonado sobre solución sin base de datos durante unos segundos

A continuación te dejo un ejemplo completo del archivo envia_emails.php que utiliza un archivo emails.txt para la lista de correos y otro archivo (emails_sent.txt) para llevar el registro de los correos que ya han sido enviados. De esta forma, el script enviará de a 50 correos pendientes por ejecución, evitando repetir envíos.

php

Copiar

<?php
// Nombres de los archivos
$emails_file = 'emails.txt'; // Archivo con la lista completa de emails (un email por línea)
$sent_file = 'emails_sent.txt'; // Archivo para registrar los emails ya enviados

// Verificar que el archivo de emails exista
if (!file_exists($emails_file)) {
die("El archivo $emails_file no existe.");
}

// Leer la lista completa de emails
$all_emails = file($emails_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

// Leer los emails que ya fueron enviados (si el archivo no existe, se asume que aún no se ha enviado ninguno)
if (file_exists($sent_file)) {
$sent_emails = file($sent_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
} else {
$sent_emails = [];
}

// Calcular la diferencia para obtener los emails pendientes
$pending_emails = array_diff($all_emails, $sent_emails);

// Seleccionar los primeros 50 emails pendientes (si hay menos, se enviarán los disponibles)
$emails_to_send = array_slice($pending_emails, 0, 50);

// Si no hay emails pendientes, finalizar el script
if (empty($emails_to_send)) {
echo "No hay emails pendientes de envío.";
exit;
}

// Configuración del email
$subject = "Asunto de tu email";
$message = "Este es el contenido del email.";
$headers = "From: [email-masked]\r\n" .
"Reply-To: [email-masked]\r\n" .
"X-Mailer: PHP/" . phpversion();

// Enviar cada email pendiente y registrarlo
foreach ($emails_to_send as $email) {
// Validar que el formato del email sea correcto
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
// Enviar el correo
if (mail($email, $subject, $message, $headers)) {
// Registrar el email enviado (agregándolo al final del archivo)
file_put_contents($sent_file, $email . "\n", FILE_APPEND);
echo "Email enviado a: $email<br>";
} else {
echo "Error al enviar email a: $email<br>";
}
} else {
echo "Formato de email no válido: $email<br>";
}
}
?>

Cómo funciona este script

Lectura de archivos:

Se lee emails.txt para obtener la lista completa de correos.

Se lee emails_sent.txt (si existe) para saber qué correos ya han sido enviados.

Determinación de correos pendientes:
Se utiliza array_diff() para obtener los correos que aún no han sido enviados, comparando la lista total con la de enviados.

Selección y envío:
Se seleccionan los primeros 50 correos pendientes con array_slice(). Luego, para cada correo, se valida su formato y se envía mediante la función mail().
Si el envío es exitoso, se registra el correo en emails_sent.txt para evitar futuros envíos duplicados.

Integración con Cron Job:
Programa la ejecución de este script cada hora (o según el intervalo que necesites) mediante un cron job. Por ejemplo:

ruby

Copiar

0 * * * * /usr/bin/php /ruta/a/tu/script/envia_emails.php

Esto hará que se ejecute al minuto 0 de cada hora, enviando hasta 50 correos pendientes sin exceder el límite de tu hosting.

Este método permite que el script "recuerde" qué correos han sido enviados gracias al archivo emails_sent.txt, sin necesidad de utilizar una base de datos. ¡Espero que te sea de utilidad!

o3-mini-high

Dijiste:

Al ser mi hosting shared, tendre acceso a cron y a esta ruta?
0 * * * * /usr/bin/php /ruta/a/tu/script/envia_emails.php

Razonado sobre acceso a cron y rutas durante 4 segundos

La disponibilidad de cron jobs en un hosting compartido depende de la configuración y las políticas de tu proveedor de hosting. Muchas veces, los proveedores de hosting compartido sí ofrecen la posibilidad de programar tareas cron a través de su panel de control (por ejemplo, cPanel o Plesk).

Aquí te dejo algunos puntos a considerar:

Acceso a Cron en Hosting Compartido:

Sí, suele estar disponible: Muchos hosting compartidos permiten configurar tareas cron mediante su panel de control.

Verifica con tu proveedor: Si no estás seguro, revisa la documentación de tu hosting o contacta con el soporte técnico para confirmar que puedes usar cron jobs.

Ruta de PHP y del Script:

La ruta /usr/bin/php es un ejemplo. En algunos hosting la ruta puede ser diferente, como /usr/local/bin/php u otra.

Para saber la ruta correcta a PHP, puedes crear un pequeño script PHP (por ejemplo, phpinfo.php) que contenga:

php

Copiar

<?php phpinfo(); ?>

y luego acceder a él por el navegador. Busca la línea que indique la ruta de PHP, o consulta la documentación de tu hosting.

La ruta /ruta/a/tu/script/envia_emails.php es un ejemplo y debes reemplazarla por la ruta real donde se encuentra tu script en el servidor.

Alternativas si no Tienes Cron:

Servicios externos: Si tu hosting no ofrece cron jobs, puedes utilizar servicios externos como EasyCron o Cron-job.org para que realicen peticiones periódicas a tu script.

Protección del script: Si optas por ejecutar el script vía una URL (por ejemplo, https://tudominio.com/envia_emails.php), asegúrate de implementar algún tipo de protección (por ejemplo, una clave secreta) para evitar que cualquier persona ejecute el script.

En resumen, es muy probable que puedas configurar cron jobs en tu hosting compartido, pero es importante que verifiques la ruta de PHP y la ubicación de tu script para configurar correctamente la tarea. ¡Consulta la documentación de tu proveedor para obtener detalles específicos!

o3-mini-high

Dijiste:

Ok, mirare a ver... Gracias Chat!!!

Razonado durante un par de segundos

¡De nada! Me alegra haber podido ayudarte. Si en algún momento tienes más dudas o necesitas asistencia adicional, aquí estaré para ayudarte. ¡Suerte con tu proyecto!

o3-mini-high

Esta conversación está archivada. Para continuar, desarchívala primero.

Desarchivar

?