You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在2天后触发邮件发送?sleep()致页面脚本延迟的解决方案咨询

How to Schedule Email Sending After 2 Days Without Blocking Your Script

Using sleep() for long delays like 2 days is a terrible idea—here's why:

  • It blocks the entire script, forcing the user to wait 2 full days for the page to load (which will never actually happen, since PHP has a maximum execution time limit, usually 30-60 seconds).
  • If the server restarts, the script crashes, or the user closes their browser, the email will never be sent.

Instead, you need to decouple the email sending from the user's request. Here are two reliable methods to do this:

Method 1: Database Queue + Cron Job (Most Reliable)

This is the standard approach for scheduled tasks. We'll store the email details in a database, then have a recurring script check for pending emails to send.

Step 1: Create a Pending Emails Table

First, make a table in your database to hold the emails waiting to be sent:

CREATE TABLE pending_emails (
    id INT AUTO_INCREMENT PRIMARY KEY,
    to_email VARCHAR(255) NOT NULL,
    subject VARCHAR(255) NOT NULL,
    message TEXT NOT NULL,
    headers TEXT NOT NULL,
    send_at DATETIME NOT NULL,
    is_sent BOOLEAN DEFAULT FALSE
);

Step 2: Save Email to Queue When User Submits

Instead of sending the email immediately, insert it into the table with a send_at timestamp set to 2 days from now:

// Your existing variables
$subject = "Application Enquiry Details";
$to = $email; // Assume $email is validated/sanitized
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset=iso-8859-1\r\n";
$headers .= "From: noreply \r\n";
$message = "your application is received";

// Calculate send time: current time + 2 days
$sendAt = date('Y-m-d H:i:s', strtotime('+2 days'));

// Insert into database (use prepared statements to prevent SQL injection!)
$pdo = new PDO('mysql:host=your_host;dbname=your_db', 'user', 'pass');
$stmt = $pdo->prepare("INSERT INTO pending_emails (to_email, subject, message, headers, send_at) VALUES (?, ?, ?, ?, ?)");
$stmt->execute([$to, $subject, $message, $headers, $sendAt]);

// Tell the user their submission was successful immediately
echo "Thank you! We'll send a confirmation email in 2 days.";

Step 3: Write a Script to Send Pending Emails

Create a standalone PHP script (e.g., send_scheduled_emails.php) that checks for unsent emails where send_at is in the past:

<?php
$pdo = new PDO('mysql:host=your_host;dbname=your_db', 'user', 'pass');

// Get all unsent emails that need to be sent now
$stmt = $pdo->prepare("SELECT * FROM pending_emails WHERE is_sent = FALSE AND send_at <= NOW()");
$stmt->execute();
$emails = $stmt->fetchAll(PDO::FETCH_ASSOC);

foreach ($emails as $email) {
    // Send the email
    $sent = mail($email['to_email'], $email['subject'], $email['message'], $email['headers']);
    
    // Mark as sent if successful
    if ($sent) {
        $updateStmt = $pdo->prepare("UPDATE pending_emails SET is_sent = TRUE WHERE id = ?");
        $updateStmt->execute([$email['id']]);
    }
}
?>

Step 4: Set Up a Cron Job

Schedule the send_scheduled_emails.php script to run periodically (e.g., every 5 minutes) using a cron job. On Linux, edit your crontab with crontab -e and add:

*/5 * * * * /usr/bin/php /path/to/your/send_scheduled_emails.php

This runs the script every 5 minutes, checking for any emails that are due to be sent.

Method 2: Use the at Command (One-Time Scheduling)

If your server supports the at command (common on Linux), you can schedule a one-time execution of the email script.

Step 1: Create a Temporary Script for the Email

When the user submits, generate a temporary PHP file with the email details:

// Your existing variables
$subject = "Application Enquiry Details";
$to = $email;
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset=iso-8859-1\r\n";
$headers .= "From: noreply \r\n";
$message = "your application is received";

// Escape variables to prevent shell injection
$escapedTo = escapeshellarg($to);
$escapedSubject = escapeshellarg($subject);
$escapedMessage = escapeshellarg($message);
$escapedHeaders = escapeshellarg($headers);

// Create a temporary script
$tempScript = "/tmp/send_email_" . uniqid() . ".php";
file_put_contents($tempScript, <<<EOT
<?php
mail($escapedTo, $escapedSubject, $escapedMessage, $escapedHeaders);
unlink(__FILE__); // Delete the script after running
EOT
);

// Make the script executable
chmod($tempScript, 0755);

// Schedule it to run in 2 days using `at`
exec("echo '/usr/bin/php $tempScript' | at now + 2 days");

// Confirm to user
echo "Thank you! We'll send a confirmation email in 2 days.";

⚠️ Security Note: Always escape variables when using exec() to prevent shell injection attacks. Also, make sure the /tmp directory is secure on your server.

Why These Methods Are Better

  • They don't block the user's request—your page loads immediately.
  • They're reliable even if the server restarts (the cron job will pick up where it left off).
  • They respect PHP's execution time limits.

内容的提问来源于stack exchange,提问作者Jobie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:28:49