0

我有一个脚本来处理发送电子邮件。可能有数千封电子邮件要发送。我想向用户显示一个页面,上面写着“正在发送您的消息。”,但我不希望该页面实际发送消息,因为我不希望用户在脚本完成之前看到一个空白页,我也不希望用户必须等待脚本完成。

我想将一个 ID 列表传递给另一个 PHP 页面(让我们称之为 run.php)并让它在没有用户实际访问的情况下执行。因此,我会将 ID 传递给开始执行的页面,然后完成加载显示消息“您的消息正在发送。”的当前页面。

<?php
/* SESSION DATA HERE */
executeMailSend($ids);
?>
<html>
<head>
....
</head>
<body>
Your messages are being sent.
</body>
</html>

我想我可以使用 ajax 来做这样的事情,但我不希望这依赖于客户端编码。

此外,如果可能的话,我需要让脚本在后台运行,以保留启动它的会话中的会话数据,并且我希望不必将此数据作为单独的变量传递。

另外,我不想使用像 exec() 或 system() 这样的东西。

有任何想法吗?

4

6 回答 6

1

利用 AJAX 的力量获取更多信息,查看 w3schools.com 提供的本教程

http://www.w3schools.com/ajax/default.asp

于 2012-12-14T03:36:37.437 回答
1

cron 作业是一种选择。您可以通过在数据库中实现一个队列来做到这一点,您只需为要发送的邮件添加条目,cron 作业会处理这些条目。但也许在走这条路之前先读一下:http ://www.engineyard.com/blog/2011/5-subtle-ways-youre-using-mysql-as-a-queue-and-why-itll-bite-你/

如果您使用 cron 作业,您将在某处实现队列(平面文件...blech、MySQL、其他数据库等)

为什么不使用实际用于排队的东西?例如,您可以使用亚马逊 (http://aws.amazon.com/sqs/)。但是,无论您使用什么软件/提供商,这听起来最好有适当的工作排队。您希望用户转到一个页面,该页面会将一些工作项添加到您的队列中(在这种情况下是电子邮件地址,可能是消息,具体取决于您正在做什么)。然后队列软件应该有一些方法来处理这些工作(即实际发送电子邮件)。

您说您不想传递变量,但您可能必须将每个作业所需的任何数据发送到您的队列。您可能会在数据库中存储额外的数据,只需考虑锁定和性能。

于 2012-12-14T03:46:03.863 回答
0

您可以让您的脚本将该电子邮件添加到“电子邮件查询”并安排一个 cron 作业来发送电子邮件。我认为没有其他方法可以异步调用 php 脚本。

也许这可以为您指明正确的方向:http ://blog.markturansky.com/archives/205

于 2012-12-14T03:39:06.670 回答
0

如果您可以使用 linux 机器;你可以使用一个叫做 Cronjobs 的东西。

您可以使用它自己的数据库表创建一个单独的脚本,以供参考。

在设定的时间间隔内,它通过 linux CLI for PHP 运行 PHP 并执行脚本,无需用户在页面上。数据库需要正确配置。

唯一的问题是 cronjobs,所有输出都通过电子邮件发送到管理电子邮件(/etc/aliases

Cronjob 输入示例:

nano /etc/crontab

* * * * *  root /usr/bin/php /var/www/cron.php 

在您的 cron.php 上,您将有一个特定功能的脚本设置,在这种情况下。电子邮件用户。

http://www.thegeekstuff.com/2011/07/php-cron-job/

于 2012-12-14T03:39:07.603 回答
0

我想我将不得不坚持我以前使用过的脚本的当前选项。我希望找到更好的选择,但这是我要使用的代码:

function backgroundPost($url){
    $parts=parse_url($url);
    $fp = fsockopen($parts['host'], isset($parts['port'])?$parts['port']:80, $errno, $errstr, 30);

    if (!$fp) {
        return false;
    } else {
        $out = "POST ".$parts['path']." HTTP/1.1\r\n";
        $out.= "Host: ".$parts['host']."\r\n";
        $out.= "Content-Type: application/x-www-form-urlencoded\r\n";
        $out.= "Content-Length: ".strlen($parts['query'])."\r\n";
        $out.= "Connection: Close\r\n\r\n";
        if (isset($parts['query'])) $out.= $parts['query'];

        fwrite($fp, $out);
        fclose($fp);
        return true;
    }
}

backgroundPost($siteURL.'/run.php?ids='.urlencode($ids).'&sessiondata='.urlencode($sessiondata));

有人看到使用这个有问题吗?安全性、错误代码等?

于 2012-12-14T03:57:57.780 回答
0

你在Linux服务器上吗?您可以 fork() 脚本(在 PHP 中)然后守护子进程,将其分离,以便在初始化 HTTP 请求完成后继续运行。只要确保正确杀死子进程即可。

http://www.re-cycledair.com/php-dark-arts-daemonizing-a-process

于 2012-12-14T05:11:52.407 回答