views:

122

answers:

7

Well basically I may want to execute a script that may take as much as 1 hours as well.

What I really want to do is Send SMS to my users using a third party API. So its basically like I supply my script with an array of phone numbers and fire the method to send SMS.

However assuming it take 5 seconds to send 1 SMS and I want to send 1000 SMS which is roughly 1 - 2 hours. I can't use set_time_limit() because I am on shared host.

One way to do this is store numbers in a session and execute each SMS and use javascript to refresh that page until end. This way I need to keep my browser open and the execution will stop if my Internet Connection is disconnected.

So, Is there any better way to do this ?

Hope I am clear enough to explain what I want? I want to execute a large script that may take hours to execute without getting timeout.

+3  A: 

PHP scripts running as CLI apps doesn't affected by max_execution_time option
So, you have no worry at all.

Col. Shrapnel
And how do I run them as CLI on a shared host? I dont think I would have access to it.
atif089
@atif just as a cron jobs. Why not to be a less ignorant?
Col. Shrapnel
yeah right. thanks :)
atif089
A: 

You can or you can't use set_time_limit()?

If you can.. Use it:

<?php
// Runs forever and ever...
set_time_limit(-1);
?>
TiuTalk
Hehe, I won't downvote because it's technically correct, but would you suggest he allow a script to run forever if he was *your* neighbour on a shared host?! :)
MatW
+3  A: 

A PHP script executed from the command-line or from a shell script, cron job, etc. does not have a timeout by default.

You can also set a PHP script's timeout dynamically with the set_time_limit() function.

Bill Karwin
+1  A: 

It's not the best options to use set_time_limit(0), because that'd means it'll run indefinitely even if you have a bug and your script enters an infinite loop.

Instead, if you estimate each SMS is going to take 5 seconds, use this approach:

while( $there_are_more_sms_to_be_sent ){
  set_time_limit(30); // enough spare time, just in case.

  // Do your sending, blah blah
}

That way, the time limit will be sequentially updated to 30 seconds. Of course you might have the infinite loop problem with that single while, but if you have other calls inside that while that limit will prevent those calls to be to blame.

Seb
so everytime it loops, is the counter reset?
atif089
That's right. I was assuming you were using a cronjob also. You should use it together with this tip, so you process, say, 100 messages each time but also you make sure you don't run out of time.
Seb
+1  A: 

If your host lets you, cron jobs are the best solution. A cron job is basically a normal php script that is automatically run by the web server at a specific time interval. For your needs I would create a script that runs every 5 mins and processes your numbers in batches of 100 (obviously you'll want to tweak the time interval and batch size to suit). This will keep your server load down and prevent you getting in trouble with your hosting provider for hogging resources.

In order to track which batch your script should be processing, I would setup a track_batch table. These columns should give you a good indication of how to approach the problem:

id, date_run, start_record, end_record, final_run

Essentially:

  • Check to see the date of the last batch run. If it isn't the current date (or whatever other identifier you choose to use) for the current batch, then proceed.
  • If the last batch run was for the current date, then check the final_run column to see whether you've already finished processing all the numbers.
  • If you still have numbers to process, use the start and end records in conjunction with MySQL's LIMIT to build the db query that your script will use to get the next batch.
  • Process your numbers.
  • Store all the info from this batch in the track_batch table.
  • If the amount of numbers the query returns is ever less than the maximum batch size, you've reached the end and can set the final_run column to 1.

Once you've got your script, you'll need to setup the cron job itself. Shared hosts are likely to have their own custom interfaces for doing this, so they are probably the best people to ask once you've got your script working.

MatW
A: 

An alternative to using JavaScript is to add the Refresh meta tag to your page:

<meta http-equiv="Refresh" content="2; url=http://yoururl/script.php&amp;step=x" ?>

The two in content="2; url=.. tells the browser to load the url 2 second after the page has loaded.

Matijs
Thanks but, I already specified this in my question. I was looking for something to be done by Server Side. I also knew about CRONs but I thought there may be more ways to this
atif089
+1  A: 

IN THE CASE YOU CAN RUN CRON JOBS

I usually have a queue, a manager and workers. Unless you can call the sms api once at the time this model can help you, and you souldn't worry about timeouts since each worker will manage it selves.

I have something like:

<?php
// PSEUDO CODE
// grab pending from queue

// <for> {
// update to running
exec("/usr/bin/php /path/to/send.php {$id} > /dev/null &");
// }

and send.php will send each sms. Right now I have this running at a rate of 300/minute since is the max frequency that you can setup on a cron job

Gabriel Sosa