7

I need a function that executes by itself in php without the help of crone. I have come up with the following code that works for me well but as it is a never-ending loop will it cause any problem to my server or script, if so could you give me some suggestion or alternatives, please. Thanks.

$interval=60; //minutes
set_time_limit(0);

while (1){
    $now=time();
    #do the routine job, trigger a php function and what not.
    sleep($interval*60-(time()-$now));
}
dreamcrash
  • 47,137
  • 25
  • 94
  • 117
alagu
  • 586
  • 1
  • 4
  • 12
  • you want a php daemon –  Sep 05 '14 at 03:13
  • Personally I wouldn't use PHP for daemon processes. There can always be memory leaks you will run into and would have to restart it every month or so. I would recommend using a different complied language instead. – Aziz Saleh Sep 05 '14 at 03:17
  • as your new to php perhaps you should explain why you need this, there is probably a better idea –  Sep 05 '14 at 03:17
  • http://stackoverflow.com/questions/9466434/what-happens-when-the-server-is-in-an-infinite-loop-and-the-client-stops – Parfait Sep 05 '14 at 03:18
  • @Dagon i am building an web app, which is basically loop through orders for every 15min and it will assign it to an free delevary man – alagu Sep 05 '14 at 04:27

4 Answers4

13

We have used the infinite loop in a live system environment to basically wait for incoming SMS and then process it. We found out that doing it this way makes the server resource intensive over time and had to restart the server in order to free up memory.

Another issue we encountered is when you execute a script with an infinite loop in your browser, even if you hit the stop button it will continue to run unless you restart Apache.

    while (1){ //infinite loop
    // write code to insert text to a file
    // The file size will still continue to grow 
    //even when you click 'stop' in your browser.
    }

The solution is to run the PHP script as a deamon on the command line. Here's how:

nohup php myscript.php &

the & puts your process in the background.

Not only we found this method to be less memory intensive but you can also kill it without restarting apache by running the following command :

kill processid

Edit: As Dagon pointed out, this is not really the true way of running PHP as a 'Daemon' but using the nohup command can be considered as the poor man's way of running a process as a daemon.

Hyder B.
  • 10,900
  • 5
  • 51
  • 60
  • calling a php script from the command line does not make it a daemon –  Sep 05 '14 at 03:29
  • This kind of process is what Apache and PHP don't do well, but what newer technologies like node.js do - IMO these kinds of tasks shouldn't be done with PHP, it's inevitably going to come back and bite you. – scrowler Sep 05 '14 at 03:33
  • @Dagon what WOULD make it a daemon? – zoltar Nov 18 '15 at 05:27
2

You can use time_sleep_until() function. It will return TRUE OR FALSE

$interval=60; //minutes
  set_time_limit( 0 );
  $sleep = $interval*60-(time());

  while ( 1 ){
     if(time() != $sleep) {
       // the looping will pause on the specific time it was set to sleep
       // it will loop again once it finish sleeping.
       time_sleep_until($sleep); 
     }
     #do the routine job, trigger a php function and what not.
   }
loki9
  • 625
  • 7
  • 20
2

There are many ways to create a daemon in php, and have been for a very long time.

Just running something in background isn't good. If it tries to print something and the console is closed, for example, the program dies.

One method I have used on linux is pcntl_fork() in a php-cli script, which basically splits your script into two PIDs. Have the parent process kill itself, and have the child process fork itself again. Again have the parent process kill itself. The child process will now be completely divorced and can happily hang out in background doing whatever you want it to do.

$i = 0;
do{
    $pid = pcntl_fork();
    if( $pid == -1 ){
        die( "Could not fork, exiting.\n" );
    }else if ( $pid != 0 ){
        // We are the parent
        die( "Level $i forking worked, exiting.\n" );
    }else{
        // We are the child.
        ++$i;
    }
}while( $i < 2 );

// This is the daemon child, do your thing here.

Unfortunately, this model has no way to restart itself if it crashes, or if the server is rebooted. (This can be resolved through creativity, but...)

To get the robustness of respawning, try an Upstart script (if you are on Ubuntu.) Here is a tutorial - but I have not yet tried this method.

Amgine
  • 141
  • 7
  • Just discovered [Run php script as a daemon process](https://stackoverflow.com/questions/2036654/run-php-script-as-daemon-process "Script Overflow question"), which answers this question more comprehensively than I have. – Amgine Sep 05 '14 at 14:54
1

while(1) means it is infinite loop. If you want to break it you should use break by condition. eg,.

while (1){ //infinite loop
    $now=time();
    #do the routine job, trigger a php function and what no.
    sleep($interval*60-(time()-$now));
    if(condition) break; //it will break when condition is true
}
MH2K9
  • 11,951
  • 7
  • 32
  • 49