tags:

views:

822

answers:

7

I have a PHP script that is called from a cron job every minute. This script takes some info from the database and then calls another PHP script using the System function (passing it some parameters).

That means that I can start up to 10 scripts from this "main" one. And what I would like to do is that I would call the script and continue the execution of the main script, that is, not wait for the System call to complete and then call the next one.

How can this be done?

A: 

use php's version of fork or threads.

J.J.
PHP doesn't support threading, but fork() is an acceptable option here.
Rob
+1  A: 

If your OS supports it, you can use the pcntl_fork() function to spin off child processes that the parent doesn't wait for. Be careful though, it is easy to accidentally create too many child processes, especially if they take longer than expected to run!

Greg Hewgill
+1  A: 

I'm not sure that PHP supports threading. Check here.

EBGreen
A: 

I think the answer would be very similar to those already provided for Asynchronous PHP calls.

da5id
A: 

You could run them in the background:

system('php yourscript.php &');

You just have to make sure that you check on the total number of processes running. All in all, not a super elegant solution. Instead cron you could let one script run for forever, I am thinking something like this:

<?php
while(true) {
  // do whatever needs to be done.
}
?>

Careful though. PHP is not exactly known to be used as a daemon.

Till
Doesn't work for me.. E.g. this script `<?php system("sleep 5 echo "Test"; ?>` still sleeps 5 seconds before writing the test message.
Gart
A: 

http://php.net/pcntl_fork

It's *NIX only but you can fork your script using the PCNTL extension.

dcousineau
+1  A: 

You may be able to use proc_open, stream_select and stream_set_blocking in concert to achieve this kind of thing.

If that sounds vague, I was going to paste a big chunk of code in here that I used in a recent project that did something similar, but then felt it may hinder rather than help! In summary though, the code worked like this:

  1. cronjob calls cronjob_wrapper.php
  2. cronjob_wrapper.php creates a new Manager class and then calls start on it.
  3. Manager class start method check to see how many instances are running (looking for pid files in a particular location). If it's less than a given max number of instances it writes out it's own process id to a pid file and then carries on
  4. Manage class creates an instance of an appropriate Encoder class and calls exec on it.
  5. The exec method uses proc_open, stream_select and stream_set_blocking to run a system command in a non-blocking fashion (running ffmpeg in this case - and could take quite a while!)
  6. When it has finally run it cleans up its PID file and bails out.

Now the reason I'm being vague and handwavy is that our multiple instances here are being handled by the cronjob not by PHP. I was trying to do very much the kind of thing you are talking about, and got something working pretty well with pcntl_fork and friends, but in the end I encountered a couple of problems (if I recall at least one was a bug in PHP) and decided that this approach was a much more rock-solid way to achieve the same thing. YMMV.

Well worth a look at those functions though, you can achieve a lot with them. Though somehow I don't think PHP will ever become the sockets programming language of choice... :)

reefnet_alex