Take the 2-minute tour ×

We are running PHP on a Windows server (a source of many problems indeed, but migrating is not an option currently). There are a few points where a user-initiated action will need to kick off a few things that take a while and about which the user doesn't need to know if they succeed or fail, such as sending off an email or making sure some third-party accounts are updated. If I could just fork with pcntl_fork(), this would be very simple, but the PCNTL functions are not available in Windows.

It seems the closest I can get is to do something of this nature:

exec( 'php-cgi.exe somescript.php' );

However, this would be far more complicated. The actions I need to kick off rely on a lot of context that already will exist in the running process; to use the above example, I'd need to figure out the essential data and supply it to the new script in some way. If I could fork, it'd just be a matter of letting the parent process return early, leaving the child to work on a few more things.

I've found a few people talking about their own work in getting various PCNTL functions compiled on Windows, but none seemed to have anything available (broken links, etc).

Despite this question having practically the same name as mine, it seems the problem was more execution timeout than needing to fork. So, is my best option to just refactor a bit to deal with calling php-cgi, or are there other options?

Edit: It seems exec() won't work for this, at least not without me figuring some other aspect of it, as it waits until the call returns. I figured I could use START, sort of like exec( 'start php-cgi.exe somescript.php' );, but it still waits until the other script finishes.

share|improve this question
have you considered a cron job for this? (there are some options available, google.com/search?q=cron+windows ) –  user187291 Mar 16 '10 at 21:27
From what I can see, it looks like that would work just as well as using psexec, but I just got things working with psexec so I'll probably just stick to that. –  Doug Kavendek Mar 17 '10 at 16:36
add comment

3 Answers

up vote 8 down vote accepted

how about installing psexec and use the -d (don't wait) option

exec('psexec -d php-cgi.exe somescript.php');
share|improve this answer
Excellent, I got that to work. I'm confused by why exec'ing with start wasn't able to do what I needed. Also, I needed to call psexec with the -accepteula parameter, even though I had already manually accepted it running it myself on the server. –  Doug Kavendek Mar 17 '10 at 16:35
add comment

Get PSExec and run the command:

exec("psexec -d php-cgi.exe myfile.php");
share|improve this answer
well this answer does have a link but the other does not –  SeanDowney Jul 11 '11 at 22:09
add comment

You can create a daemon/background process to run the code (e.g. sending emails) and the request would just have to add items to the queue, let the deamon do the heavy lifting.

For example, a file send_emails.bat:

C:\PHP533\php.exe D:\web\server.php

open windows task scheduler, and have the above send_emails.bat run every 30 minutes. Make sure only one instance runs at a time or you might run each task in multiples, or send each email twice. I say 30 minutes in case something breaks temporarily (memory issues, database unavailable, etc), it will re-start every 30 minutes rather than having a never ending process that just stops. The following is a skeleton daemon... not complete or tested I am just typing out an example:

set_time_limit(60*30); // don't run
$keepgoing = true;
$timeout = time()+ 60*29; // 29 minutes

while(time() < $timeout)
    // grab emails from database
    $result = $db->query('select subject, body, to_email FROM email_queue');
    if($result->num_rows == 0)
        sleep(10); // so we are not taxing the database 
        // send email

Finally you just need the request to add the item to the queue in a database, and let the daemon handle the heavy lifting.

$db->query('insert into email_queue(to,subject,body) values ('customer@email.com','important email','<b>html body!</b>');
share|improve this answer
add comment

Your Answer


