Forking in PHP on Windows

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

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

PSTools are a good patch in, but I'll leave this here:
If your server runs windows 10 and it has the latest updates, you can install a Linux subsystem, which has its own Kernel that supports native forking. This is supported by Microsoft officially.

Here's a good guide on how to do it.

Once you've installed the subsystem itself, you need to install php on the subsystem.

Your windows "c:\" drive can be found under "/mnt/c", so you can run your php from the subsystem, which supports forking (and by extension the subsystem's php can use pcntl_fork).

Example: php /mnt/c/xampp/htdocs/test.php

If you want to run the subsystem's php directly from a windows command line you can simply use the "wsl" command.

Assuming you're running this from under "C:\xampp\htdocs\"
Example: wsl php main.php

The "wsl" command will resolve the path for you, so you don't need to do any dark magic, if you call the command under c:\xampp\htdocs, the subsystem will resolve it as "/mnt/c/xampp/htdocs/".

If you're running your server as an apache server, you don't really need to do anything extra, just stop the windows apache server and start the linux one and you're done. Obviously you'll need to install all the missing php modules that you need on the subsystem.


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:

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

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:

<?php
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 
    }
    else
    {
        while($row = $result->fetch_assoc())
        {
        // send email
        }
    }
}
exit;
?>

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 ('[email protected]','important email','<b>html body!</b>');

Get PSExec and run the command:

exec("psexec -d php-cgi.exe myfile.php");

Tags:

Windows

Php

Fork