Php 使用Symfony进程组件的Ajax轮询

Php 使用Symfony进程组件的Ajax轮询,php,ajax,symfony,symfony-process,Php,Ajax,Symfony,Symfony Process,我正在启动一个长时间运行的任务,该任务通过Symfony流程组件返回有关任务进度的增量输出 其中一个示例演示如何获取实时输出,另一个示例演示如何运行异步任务 我试图实现的是将getIncrementalOutput的结果传递回ajax轮询函数,以便实时更新前端 在这两种情况下,进程->start()似乎都被阻塞了,因为我的ajax调用需要一分钟才能返回,到那时任务已经完成 我想我是在试图避免将进度写入db或文件,而直接从正在运行的PHP任务获取输出 不确定这是否可能。虽然我不完全理解您想要创建什

我正在启动一个长时间运行的任务,该任务通过Symfony流程组件返回有关任务进度的增量输出

其中一个示例演示如何获取实时输出,另一个示例演示如何运行异步任务

我试图实现的是将getIncrementalOutput的结果传递回ajax轮询函数,以便实时更新前端

在这两种情况下,进程->start()似乎都被阻塞了,因为我的ajax调用需要一分钟才能返回,到那时任务已经完成

我想我是在试图避免将进度写入db或文件,而直接从正在运行的PHP任务获取输出


不确定这是否可能。

虽然我不完全理解您想要创建什么,但我已经写了一些类似的东西,看看它可能会回答您的问题:

首先,我创建了一个执行长期运行任务的命令:

class GenerateCardBarcodesCommand extends Command 
{
    protected function configure()
    {
        $this
            ->setName('app:generate-card-barcodes')
            ->setDescription('Generate the customer cards with barcodes')
            ->addArgument('id', InputArgument::REQUIRED, 'id of the Loy/Card entity')
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $id = $input->getArgument('id');
        // generate stuff and put them in the database
    }
}
在控制器中,流程启动,并且有一个ajax操作

class CardController extends Controller
{
    public function newAction(Request $request)
    {
                // run command in background to start generating barcodes
                // NOTE: unset DYLD_LIBRARY_PATH is a fix for MacOSX develop using MAMP.
                // @see http://stackoverflow.com/questions/19008960/phantomjs-on-mac-os-x-works-from-the-command-line-not-via-exec
                $process = new Process(sprintf('unset DYLD_LIBRARY_PATH ; php ../../apps/spin/console spin:loy:generate-card-barcodes %d', $entity->getId()));
                $process->start();

                sleep(1); // wait for process to start

                // check for errors and output them through flashbag
                if (!$process->isRunning())
                    if (!$process->isSuccessful())
                        $this->get('session')->getFlashBag()->add('error', "Oops! The process fininished with an error:".$process->getErrorOutput());

                // otherwise assume the process is still running. It's progress will be displayed on the card index
                return $this->redirect($this->generateUrl('loy_card'));
     }

    public function ajaxCreateBarcodesAction($id)
    {
        $em = $this->getDoctrine()->getManager();
        $entity = $this->getEntity($id);
        $count = (int)$em->getRepository('ExtendasSpinBundle:Loy\CustomerCard')->getCount($entity);
        return new Response(floor($count / ($entity->getNoCards() / 100)));
    }
}
//在twig模板中检索ajax,它只是一个0到100之间的数字,用于jQueryUIProgressBar。 {{‘处理’|反}}

            <script type="text/javascript">
            $(function() {
                function pollLatestResponse() {
                    $.get("{{ path('loy_card_ajax_generate_barcodes', {'id': entity[0].id}) }}").done(function (perc) {
                        if (perc == 100)
                        {
                            clearInterval(pollTimer);
                            $('#download-{{entity[0].id}}').show();
                            $('#progress-{{entity[0].id}}').hide();
                        }
                        else
                        {
                            $('#progress-{{entity[0].id}}').progressbar("value", parseInt(perc));
                        }
                    });
                }

                var pollTimer;
                $(document).ready(function () {
                    $('#progress-{{entity[0].id}}').progressbar({"value": false});
                    pollTimer = setInterval(pollLatestResponse, 2000);
                });
            });
            </script>

$(函数(){
函数pollatestresponse(){
$.get(“{path({loy\u card\u ajax\u generate\u barcode',{'id':entity[0].id})}”).done(函数(perc){
如果(perc==100)
{
清除间隔(轮询计时器);
$('#下载-{{entity[0].id}}}').show();
$('#progress-{{entity[0].id}}}').hide();
}
其他的
{
$('#progress-{{entity[0].id}}}').progressbar(“value”,parseInt(perc));
}
});
}
无功脉冲定时器;
$(文档).ready(函数(){
$('#progress-{{entity[0].id}}}').progressbar({“value”:false});
pollTimer=setInterval(PollLatesResponse,2000);
});
});

我可能错了,但我认为它会生成主PHP进程的子进程,因此就请求生命周期而言,它仍然是阻塞的,它不会阻塞您在该请求过程中可能要做的其他事情。你不能启动子程序。。。返回一个响应,然后使用第二个请求对其进行检查。我想你需要排队。啊,我明白你的意思了。也许是这样