Reputation: 464
I have a script to process sending emails. There could be thousands of emails to send. I want to show the user a page that says something along the lines of "Your messages are being sent.", but I don't want that page to do the actual sending of the messages, because I don't want the user to see a blank page until the script finishes and I also don't want the user to have to wait for the script to finish.
I would like to pass a list of IDs to another PHP page (lets call it run.php) and have it execute without having the user actually visit it. So I would pass the IDs to the page, which starts the execution, but then finishes loading the current page which shows the message "Your messages are being sent.".
<?php
/* SESSION DATA HERE */
executeMailSend($ids);
?>
<html>
<head>
....
</head>
<body>
Your messages are being sent.
</body>
</html>
I think I could something like this using ajax, but I would prefer to not make this rely on client side coding.
Also, if at all possible, I need to have the script running in the background keep session data from the session that starts it, and I would prefer that I don't have to pass this data along as separate variables.
Also, I don't want to use anything like exec() or system().
Any ideas?
Upvotes: 0
Views: 539
Reputation: 1835
Are you on Linux server? You can fork() the script (within PHP) then daemonize the child process, detaching it so that it continues to run after the initializing HTTP request is finalized. Just make sure to kill the child processes correctly.
http://www.re-cycledair.com/php-dark-arts-daemonizing-a-process
Upvotes: 0
Reputation: 464
I guess I will have to stick with my current option which is script I've used before. I was hoping to find a better option, but here is the code I am going to use:
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));
Does anyone see a problem with using this? Security, bad code, etc?
Upvotes: 0
Reputation: 5567
A cron job is one option. You could do it by implementing a queue in the database, you'd just add entries for the mail to be sent and the cron job processes those entries. But maybe read this before going down that road: http://www.engineyard.com/blog/2011/5-subtle-ways-youre-using-mysql-as-a-queue-and-why-itll-bite-you/
If you use a cron job, you're going to be implementing a queue somewhere (flat file...blech, MySQL, other DB, etc.)
Why not use something that is actually made for queuing? For example you could use Amazon (http://aws.amazon.com/sqs/). But whatever software/provider you use, this sounds like it would be best with proper job queuing. You want the user to go to a page which will add some work items to your queue (which in this case are email addresses and maybe messages depending on exactly what you are doing). Then the queue software should have some means of processing these jobs (i.e. actually sending the emails).
You say you don't want to pass variables, but you'd likely have to send whatever data you need for each job to your queue. You could potentially store extra data to your database, just think about locking and performance.
Upvotes: 1
Reputation: 5524
if you have access to a linux box; you can use something called Cronjobs.
You can create a separate script with it's own database table, which it uses for reference.
on a set interval it runs PHP through the linux CLI for PHP and executes the script, no user needs to be on the page. the database needs to be configured properly though.
Only problem is with cronjobs, all output is emailed to the administration E-mail (/etc/aliases
Example on Cronjob input:
nano /etc/crontab
* * * * * root /usr/bin/php /var/www/cron.php
and on your cron.php you will have a script setup for a specific function, in this case. E-mail users.
http://www.thegeekstuff.com/2011/07/php-cron-job/
Upvotes: 0
Reputation:
You could make your script add that email to 'email query' and schedule a cron job to send emails. I don't think there is other way to call php script asynchronously.
Maybe this could point you in right direction: http://blog.markturansky.com/archives/205
Upvotes: 0
Reputation: 1420
Utilize the power of AJAX for more information checkout this tutorial by w3schools.com
http://www.w3schools.com/ajax/default.asp
Upvotes: 1