Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP+fork(): How to run a fork in a PHP code

I am running my code on CodeIgniter - Ubuntu Server.

I have been researching for async ways to run functions.

This is my function:

<?php   

    // Registers a new keyword for prod to the DB. 
    public function add_keyword() {

        $keyword_p = $this->input->post('key_word');

        $prod      = $this->input->post('prod_name');
        $prod      = $this->kas_model->search_prod_name($prod);
        $prod      = $prod[0]->prod_id;

        $country   = $this->input->post('key_country');

        $keyword = explode(", ", $keyword_p);
        var_dump($keyword); 
        $keyword_count = count($keyword);
        echo "the keyword count: $keyword_count";

        // problematic part that needs forking
        for ($i=0; $i < $keyword_count ; $i++) { 

            // get new vars from $keyword_count
            // run API functions to get new data_arrays
            // inserts new data for each $keyword_count to the DB 

        }

        // Redirect to main page. 
        redirect('banana/kas'); 

    }

The "foreach" uses variables with slow APIs, and updates the database.

I saw some tutorials using fork but haven't quite understood the syntax part of it. Most of the things I found were just explanations of how it works (2 processes: parent-child ect') but non-gave a good explanation of how applying this on the code.

Can someone explain how I work with the fork() syntax?

Continue PHP execution after sending HTTP response

http://www.onlinetechtutorials.com/2014/06/how-to-run-php-code-asynchronously.html

http://php.net/manual/en/function.pcntl-fork.php (more general)

From the server side: https://www.youtube.com/watch?v=xVSPv-9x3gk

EDIT:

Did I get it right?

<?php   

// Registers a new keyword for prod to the DB. 
public function add_keyword() {

    $keyword_p = $this->input->post('key_word');

    $prod      = $this->input->post('prod_name');
    $prod      = $this->kas_model->search_prod_name($prod);
    $prod      = $prod[0]->prod_id;

    $country   = $this->input->post('key_country');

    $keyword = explode(", ", $keyword_p);
    var_dump($keyword); 
    $keyword_count = count($keyword);
    echo "the keyword count: $keyword_count";

    for ($i=0; $i < $keyword_count ; $i++) { 
        // create your next fork
        $pid = pcntl_fork();

        if(!$pid){
            //*** get new vars from $keyword_count
            //*** run API functions to get new data_arrays
            //*** inserts new data for each $keyword_count to the DB 
            print "In child $i\n";
            exit($i);
            // end child
        }
    }

    // we are the parent (main), check child's (optional)
    while(pcntl_waitpid(0, $status) != -1){
        $status = pcntl_wexitstatus($status);
         echo "Child $status completed\n";
    }

    // your other main code: Redirect to main page. 
    redirect('banana/kas'); 

}
?>

This won't cause any problem with using this inside a loop? will it know to stack each process?

like image 748
Imnotapotato Avatar asked Mar 31 '16 09:03

Imnotapotato


People also ask

How do I fork a process in PHP?

PHP Multiprocessing Creating child process using fork php // $pid is the PID of child $pid = pcntl_fork(); if ($pid == -1) { die('Error while creating child process'); } else if ($pid) { // Parent process } else { // Child process } ?>

What is Pcntl_fork?

The pcntl_fork() function creates a child process that differs from the parent process only in its PID and PPID. Please see your system's fork(2) man page for specific details as to how fork works on your system.


2 Answers

You must mention what's the operating system that you are using, because pcntl extensions are not available on Windows platform
Also you must be aware that activating process control on Linux/Unix within a web server can give you unexpected results, so only CLI/CGI mode is recommended to use PCNTL
Please read carefully this PCNTL Introduction

Now, your code seems to be correct and well implemented, but you must compile your PHP with this option --enable-pcntl to enable pcntl functions like int pcntl_fork(void) otherwise you will get

Fatal error: Call to undefined function pcntl_fork()

For me, the best solution to run functions/methods in asynchronous way is to use pthreads, if you are interested by this advice i can edit my response by adding examples and how to install it on Windows or Linux platforms

Read this article to know how to compile PHP

like image 90
Halayem Anis Avatar answered Sep 29 '22 04:09

Halayem Anis


You have one fork after your pcntl_fork(), check $pid and then you can use it. Repeat for more forks.

<?php
    for($i = 1; $i <= 3; ++$i){
        // create your next fork
        $pid = pcntl_fork();

        if(!$pid){
            // begin child, your execution code
            sleep(1);
            print "In child $i\n";
            exit($i);
            // end child
        }
    }

    // we are the parent (main), check child's (optional)
    while(pcntl_waitpid(0, $status) != -1){
        $status = pcntl_wexitstatus($status);
        echo "Child $status completed\n";
    }
    // your other main code
?>

For async http requests you can use multicurl: http://php.net/manual/en/function.curl-multi-init.php

like image 31
thecoder Avatar answered Sep 29 '22 05:09

thecoder