Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 158
  • Last Modified:

How to fire off PHP script/page in background?

I have a PHP script that rolls through a large table of email addresses and sends out a newsletter based on custom content drawn from the database.  On average I calculate this script to take 2 minutes or so to run.

Is there a way to fire off the process in the background so that the page does not have to wait to be loaded in the browser?  I am afraid that those who are running the mailing script will close the window or hit stop and screw things up.  Can I somehow run it in the background or are there other ideas?  Thanks!

FYI, I am on a shared hosted webserver, so I don't have root access to anything.
0
djs120
Asked:
djs120
1 Solution
 
KoorooCommented:
a couple of options. but I have to ask, this will be a user initiated request to fire off these emails?

One way to do it is via a trigger somewhere.
-Essentially, when a user visits your page and submits a request to fire off the newsletter, all your script does is create a 0-byte file in your home directory.
-You have a cron job running under your username(most shared hosting have control panels to create cron/scheduled jobs) that runs every minute. All this job does is this:
if trigger file exists, call the php script via a curl or just a shell execute since it won't return anything, then erase the trigger file.

so now what you've done is taken away the long running process from your end user and turned it into a trivially short one (touch a file). and the cron job should also be trivially small until it senses that you actually need the job run so it shouldn't be too big a deal to run it fairly frequently.
0
 
KoorooCommented:
ps. - also, this will keep multiple users from sending out your mailing list a bagillion times simultaneously and pissing off your host.
pps - don't forget to double check with your host that you are able to send out all these emails off their smtp.
0
 
djs120Author Commented:
Unfortunately my host is really crappy and I can't set up cron jobs from the control panel.  I doubt the host will set one up for me.  Is there something I can do using the PHP exec() command or system() command (or something close to that?).
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
KoorooCommented:
what host is this? do they offer shell access? you could do it via command line if they do.

another solution is to look at the reference for the php function set_time_limit(). This isn't an absolute solution though because you'll still be bound by global settings...but it should prevent users from messing your script up with a stop.

It is my opinion that the cron job is best because it eliminates user misfunction fairly cleanly.
0
 
quad341Commented:
all you need to do is ignore user abort.  depending on they type of server depends on the setting.  true for *nix, false for some versions of windows.

just add to the top of the script:
ignore_user_abort(true); // for *nix
0
 
wascoCommented:
what i do if i have to write things like this for customers is the following

on top of the page i have the following code
session_start();
if(!isset($_SESSION['current'])) { $_SESSION['current'] = 0; }

then i query the db to get the first 10 record
"SELECT * FROM emails order by emailaddress LIMIT " .  $_SESSION['current'] . ",10"

this takes 10 email addresses of the db.
then send the emails to those people

last but not least,
 $_SESSION['current'] =  $_SESSION['current']+10;
header('location: ' . $_SERVER['PHP_SELF']);

so the script takes 10 email adresses of the list
when finished forwards to itself to do the next 10

alternatively you could create a new column in your db to keep track of what record has its email send and instead of using a session-current var, just select 10 records that havent been send
if no record are found, your script is finished and you can show a text onscreen to congrats the user.

i've once taken it a little further by showing the user the progress of the operation
at the beginning of the script i show a percentage on the screen
when the emails are send instead of using the header (which cant be used after showing something on screen) i used javascript's document.location.href to start the next batch
by doing this the user could see the progress of the email sending

0
 
Marcus BointonCommented:
If you can get decent access, this is the 'proper' way to keep a PHP script running all the time in the background:

http://www.experts-exchange.com/Web/Web_Languages/PHP/Q_20977409.html

I use this mechanism for sending out mailing lists.
0
 
djs120Author Commented:
I like your idea, wasco, with showing the user progress on the task.  I will try implementing this and will return to post the solution here...
0
 
djs120Author Commented:
Wasco, I used your idea and did the % bar feature by using a META REFRESH to change the location and display how many records have been completed so far:

<META HTTP-EQUIV="Refresh" CONTENT="1; URL=<?=$_SERVER['PHP_SELF']?>">

Thanks!
0

Featured Post

Receive 1:1 tech help

Solve your biggest tech problems alongside global tech experts with 1:1 help.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now