Search code examples
phpasynchronousexecution

PHP call function in separate process


sorry for long text.

I am looking for an idea to trigger execution of php function (in different directory, tested and in same directory) when specific act occurs.

System is Debian and php framework yii.

With API we receive new data from remote server and for specific value in data we receive I need to start function in separate process. No need to wait for its completion. Because API response time I can't integrate this function into it and integration breaks down API rendering it unusable.

I have read dozens of answers on Stackoverflow and many other examples.

For test I just tried to create new folder at specific location and file wasn't created (permission problem I think but can't confirm since it makes it if done from main code - api). It is supposed to do following:

  • pass 2 arguments received from API to function
  • create folder if it doesn't exist
  • call internal class that uses fpdf to print pdf file.
  • save document and mail it with PHPMailer.

Can't use pcntl_fork because it requires additional installation (which I am not allowed to do).

Covered topics:

  • forking with pcntl_fork (execution stops on reaching it.)
  • popen/pclose, exec, proc_open/proc_close (no reply and can't confirm it actually entered function).

Of course this situation excludes possibility of use of include and require.

Can't release api code but here is what I was asking it to do:

background.php

$docs_dir='test_folder';
if (!file_exists('/var/www/created_documents/'.$docs_dir))
{
    mkdir('/var/www/created_documents/'.$docs_dir, 0777, true);
    chmod('/var/www/created_documents/'.$docs_dir, 0777);
}

And it does nothing.

Few examples what I used in api code to jump to it (many others were deleted during work).

$proc = popen('php ' . __DIR__ . '/background.php &', 'r');
return $proc;
while (!feof($proc))
{
    $data = fgets($proc);
    var_dump($data);
}


exec("php background.php");


$cmd = "php background.php";
$timer = popen("start ". $cmd, "r");
pclose($timer);


exec($cmd . " > /dev/null &");
pclose(popen("php background.php &","r"));

Solution

  • You could make a separate internal http request using curl and its async funcionality.

    Or you may use a queuing mechanism where one part is firing an event and the other part is consuming it. RabbitMQ or Gearman could do this for you.