PHP CodeIgniter:如何在后台运行进程而不会让我的整个网站卡住

时间:2016-04-06 12:12:43

标签: php asynchronous process

我在Ubuntu LAMP服务器上有一个网站 - 它有一个获取变量的表单,然后它们被提交给一个处理它们的函数。该函数调用控制器中的其他函数“爆炸”变量,在数组中对它们进行排序并在每个变量上运行“for”循环,从慢速API获取新数据,并将新数据插入数据库中的相关表。

每当我提交表单时,整个网站都会被卡住(仅限我的IP,其他桌面上的网站会继续定期工作),我会被重定向,直到我找到所请求的“重定向(”new / url);“ 。

我一直在研究这个问题,并发现这篇文章是一个例子:   Continue PHP execution after sending HTTP response

在研究了如何在服务器端工作之后,在本视频中解释得非常好:https://www.youtube.com/watch?v=xVSPv-9x3gk

我想开始学习如何编写它的语法,并发现这只适用于CLI,而不是来自APACHE,但我不确定。

我几天前发了这篇文章:PHP+fork(): How to run a fork in a PHP code

并且从服务器端获取所有工作后,安装fork并找出服务器中php.ini文件的差异(我编辑了apache2 php.ini,不要弄错),我停止了错误我曾经得到“fork”,但进程不在后台运行,我没有被重定向。

这是添加fork后的控制器:

<?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'); 

}
?>

这是没有前叉的控制器:

// 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'); 

}

for ($i=0; $i < $keyword_count ; $i++) {是我想在后台运行的部分,因为它花费了太多时间。

现在:

  1. 我怎样才能按照我解释的方式工作?因为从我看来,fork不是我正在寻找的,或者我可能做错了。

  2. 我很乐意学习新技术,所以我很乐意得到关于如何以不同方式做到这一点的建议。我是一个自学者,我发现了Node.js在exmaple方面的巨大优势,如果我能学到它,它可以在这种情况下完美地工作。我将考虑将来学习如何使用Node.js.发送服务器请求和获取响应非常棒;)。

  3. *****如果需要添加更多关于某些内容的信息,请在评论中告诉我,如果您认为相关内容我会错过,我会在帖子中添加更多信息。

1 个答案:

答案 0 :(得分:1)

你真正想要的是队列或工作系统。有一个脚本一直在运行,等待一些事情要做。一旦你的原始PHP脚本运行,它只是将一个作业添加到列表中,它可以正常地继续它的过程。

有一些实现 - 看看像https://laravel.com/docs/5.1/queues

这样的东西