如何在不将用户保留在页面上的情况下从PHP执行PHP脚本?

时间:2012-12-14 03:33:28

标签: php

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

我想将一个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()这样的东西。

有什么想法吗?

6 个答案:

答案 0 :(得分:1)

利用AJAX的强大功能获取更多信息,请通过w3schools.com查看本教程

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

答案 1 :(得分:1)

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

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

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

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

如果你有权访问linux盒子;你可以使用一种叫做Cronjobs的东西。

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

在设定的时间间隔内,它通过用于PHP的Linux CLI运行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/

答案 4 :(得分: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));

是否有人发现使用此问题?安全性,错误的代码等?

答案 5 :(得分:0)

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

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