Solved

PHP Script execute at a specific time

Posted on 2004-09-23
18
367 Views
Last Modified: 2010-05-18
Hi,

I have a PHP deamon running which spawns a new PHP process at particular times.
This process can take between 1 and 10 seconds. However, one line of the code needs to be executed on (or after) a specific system clock time (at the seconds level).
Is there a function available, or could one be written to determine if the particular time has passed yet?

Thanks,
Adam
0
Comment
Question by:adamcable
  • 4
  • 3
  • 3
  • +3
18 Comments
 
LVL 27

Accepted Solution

by:
Diablo84 earned 43 total points
ID: 12131735
A simple approach would be

<?php
$exec_time = "11:21:52"; //HH:MM:SS
$parts = explode(":",$exec_time);
$exec_time = mktime($parts[0],$parts[1],$parts[2]);

if ($exec_time <=  time()) {
 echo "exec time has been reached or passed";
}
?>
0
 
LVL 48

Assisted Solution

by:hernst42
hernst42 earned 41 total points
ID: 12131738
You can get the current time with the time() -function if the time is greater than the time you expect it has passed

example:
$nexttime = time() +30;
while(true) {
if (time()>$nexttime) {
  // execute line
  $nexttime = time() +30;
}
sleep(rand(1,10));
}
0
 
LVL 7

Assisted Solution

by:jdpipe
jdpipe earned 41 total points
ID: 12133108
You said that one line of code needs to execute at a specific time.

I would suggest that just before the line of code in question, you put a command like this, assuming $time contains the unix time that you want the command to occur:

...
sleep($time - time());
perform_timed_code(...);

If you're kicking off this script all the time, maybe every minute, then you don't want the the program to sleep for too long ($maxsleepseconds), so you'd put in some more logic:

$sleepseconds = $time - time();
if($sleepseconds < $maxsleepseconds){
    sleep($sleepseconds);
}
perform_timed_code(...);

I don't know how you're running that daemon, or whether it's a cron job or whatever, so it's hard to say much more for now...
0
 
LVL 4

Expert Comment

by:Skonen
ID: 12134914
This function should help you out:

function process_wait($iTimeStamp, $voidFunc) {
           
           $iArgNum = func_num_args();      // Number of arguments
           $aPassedArgs = func_get_args();  // Arguments passed

           while (time() < $iTimeStamp) {
                 sleep(1);   //Conserve resources
           }

           for ($i=1; $i < $iArgNum; $i++){
                call_user_func($aPassedArgs[$i]);
           }
}

It has the ability to take varying length arguments, but at the current time I made it so all functions passed must not require any variables to be passed.

Here is an example of it's usage:

function test_func() {
     echo "Time passed- Function 1 Executed";
}

function test_func2() {
     echo "Time passed- Function 2 Executed";
}

// Example, perform both functions after 5 seconds:
process_wait(time()+5, 'test_func', 'test_func2');

// Example, perform only function two after 5 seconds:
process_wait(time()+5, 'test_func2');

//Example, using Diablo's time format
$exec_time = "11:21:52"; //HH:MM:SS
$parts = explode(":",$exec_time);
$exec_time = mktime($parts[0],$parts[1],$parts[2]);
process_wait(time()+5, 'test_func');



Good luck,
        Stuart Konen



0
 
LVL 4

Expert Comment

by:Skonen
ID: 12134976
The above function will wait until the time has passed, if you want to continue with script execution and only execute the functions if the time has passed, and not wait for it. Use this:

function process_wait($iTimeStamp, $voidFunc) {
           
           $iArgNum = func_num_args();      // Number of arguments
           $aPassedArgs = func_get_args();  // Arguments passed

           if (time() < $iTimeStamp) {
                 //Time has not passed, exit function
                 return;
           }

           for ($i=1; $i < $iArgNum; $i++){
                call_user_func($aPassedArgs[$i]);
           }
}


The same rules for usage apply, only now it does not wait for the time to pass.
0
 

Author Comment

by:adamcable
ID: 12140718
The php daemon is just being run from the unix level, and constantly monitors our database for particular jobs to occur.
When a job occurs, it spawns a child, which runs the job.

To be honest, I'm most probably going to use the easier "sleep($time - time());->perform_timed_code(...);" code. My only concern is that does sleep allow a negative number here? ie, if the time has already elapsed will a null sleep occur, and the code carry on.
If not, I guess just a nice if statement is all that's needed to detect whether the time has elapsed already, unless there is a better way?

Thanks,

Adam
0
 
LVL 11

Expert Comment

by:neester
ID: 12142250
Hey AdamCable
Have you tried using CRONTAB ?

http://www.clockwatchers.com/cron_main.html

That should get you started :)
very simple, you can set a "process" to exectue every day, on the 5th second of every minute. or every second every minute.. etc...

Very useful and powerful!
0
Easy Project Management (No User Manual Required)

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:adamcable
ID: 12145436
Neester,

I have considered using cron jobs, but as I am contacting remote systems at the beginning of the script execution, there is obviously a time variance that can occur here.
Unfortunately it's not the case of getting everything done as quickly as possible, but to execute a specific line at a particular time.

Many thanks,
Adam
0
 
LVL 11

Expert Comment

by:neester
ID: 12145582
Hmm.

Well adam, to do what you want, exactly on the dot etc...
it wont be possible with php, unless you set the script to loop forever, and just check what time its up to.
which will basuically overload the server just getting the timing right...
0
 
LVL 7

Expert Comment

by:jdpipe
ID: 12149590
Hey Adam

Yep I reckon a little if statement just the trick, go for the following. I changed time to microtime and sleep to usleep - that will give you sub-second accuracy:

Looks like you can't get sub-second accuracy on Windows, my testing showed the following script took 1.999 seconds. Expect it would work fine on Unix/Linux though.

<?php

$maxsleepseconds=10;

define('IS_WINDOWS',(substr(php_uname(), 0, 7) == "Windows"));

list($usec,$sec)=split(" ",microtime(true));
$currenttime=((float)$usec)+((float)$sec);

// presumably this would be specified from a schedule etc etc:
$time=$currenttime+2.5;

print("Current time: ".$currenttime."\n");
print("Trigger time:  ".$time."\n");

$sleepseconds = (float)$time - $currenttime;
if($sleepseconds < $maxsleepseconds && $sleepseconds > 0){
    print("Sleeping for $sleepseconds...\n");
    if(IS_WINDOWS){
          sleep($sleepseconds);
    }else{
          usleep($sleepseconds*1e6);
    }
    print("Performing code now...\n");
    // perform_timed_code(...);
}else{
    print("Skipping...\n");
}

list($usec,$sec)=split(" ",microtime(true));
$newtime=((float)$usec)+((float)$sec);

print("Script time: ".($newtime-$currenttime)." sec");

?>
0
 

Author Comment

by:adamcable
ID: 12155803
All,

Thanks for this.
All the answers look feasible how. However, how do I overcome the midnight issue? ie - Say the job had to run at 00:00:05, and the script executed at 23:59, it would issue the command automatically as it is past 00:00:05.
I guess I'd need to include the date too, but which is the best way?

Thanks,
Adam
0
 
LVL 27

Expert Comment

by:Diablo84
ID: 12155837
Heres an expanded version of my original example:

<?php
$day = 26;
$month = 9;
$year = 2004;
$hours = 20;
$minutes = 3;
$seconds = 45;

$exec_time = mktime($hours,$minutes,$seconds,$month,$day,$year);

if ($exec_time <=  time()) {
 echo "exec time has been reached or passed";
}
?>
0
 
LVL 7

Expert Comment

by:jdpipe
ID: 12156844
Adam

The dat problem is no problem:  the time() function return the sime as a number of seconds from a set time in the past ("the start of the unix epoch"). So if the script runs of the midnight changeover, no probs. You will need to give thought to how you set up your schedule (the $time) variable in my example. For example, to run the script each hour on the hour,

$time=floor(time()/3600+1)*3600;
$maxsleepseconds=60;

If it's vitally important that your script exactly every hour (or whatever) and never miss one you will need to know how long the earlier tasks in your process take and then work out how often you need to kick off the php script.

Of course you've got daylight savings etc etc to think about too, if you get really serious.
0
 
LVL 27

Expert Comment

by:Diablo84
ID: 12492654
As far as i can tell enough information has been provided to obtain a conclusive answer, so i advise a split as follows:

Diablo84 & hernst42 & jdpipe
0
 
LVL 7

Expert Comment

by:jdpipe
ID: 12522153
Sounds good to me too

JP
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Consider the following scenario: You are working on a website and make something great - something that lets the server work with information submitted by your users. This could be anything, from a simple guestbook to a e-Money solution. But what…
These days socially coordinated efforts have turned into a critical requirement for enterprises.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now