PHP,Apache。在脚本完成之前输出对浏览器的响应

时间:2013-02-27 17:54:02

标签: php output-buffering

我有一个脚本,可以从数据库中提取用户,准备XMPP消息,遍历每个用户并发送XMPP消息,然后记录消息已发送。轻松运行1000多个用户。这是从移动设备调用的服务器端API脚本。移动设备正在等待接收成功的JSON响应。用户体验应该很快,我不希望移动用户等待超过几秒钟的响应。

问题是脚本需要花费相当多的时间来遍历所有用户,因此我的初始解决方案是使用ob_flush() - 请注意这些只是测试脚本以查看计划的方法是否有效:

    ob_start(); 

$profiles_ar = array(
    "reach" => 30,
);

$return_ar = array(
    "success"   => $profiles_ar['reach'],
);

echo json_encode($return_ar);

$buffer = str_repeat(" ", 4096);                    // Note apparently  the buffer must be "filled" with 4096 characters (bytes?) for ob_flush() to work before sleep() occurs.

echo $buffer;

ob_flush();

flush();

for($i=0;$i < $profiles_ar['reach']; $i++)
{
   sleep(1);
}

echo "finshed: ".$i;

ob_flush();

flush();

这不起作用,在脚本完成之前没有输出 - 我是否错过了OB技术?

......所以做了一些搜索并想出了这个:

register_shutdown_function('process_after');

$profiles_ar = array(
    "reach" => 10,
);

$return_ar = array(
    "success"   => $profiles_ar['reach'],
);

echo json_encode($return_ar);


echo $buffer;

exit;

function process_after()
{
    global $profiles_ar;

    for($i=0;$i < $profiles_ar['reach']; $i++)
    {
       sleep(1);
    }

    echo "finshed: ".$i;
}

这个适用于mac,但不适用于服务器....

有人有任何想法吗?如果我不能在主处理工作之前得到这种输出响应JSON的技术,那么我唯一的希望是在数据库中构建一个队列并运行一个cron作业........;(

2 个答案:

答案 0 :(得分:1)

php.ini中是否启用了output_buffering? http://php.net/manual/en/outcontrol.configuration.php

我会在它自己的文件中重构xmpp消息的创建,然后使用ajax调用来发送每个消息。这样你就不会等待每条消息都能成功。

答案 1 :(得分:1)

解决方案是添加:

    echo " ";
    ob_flush(); flush;

在循环内......

ob_start(); 

$profiles_ar = array(
    "reach" => 10,
);

$return_ar = array(
    "success"   => $profiles_ar['reach'],
);

echo json_encode($return_ar);

for($i = 0; $i < 5000; $i++)
{
    echo " ";
    ob_flush(); flush;
}

echo $buffer;

ob_flush();

flush();

ob_end_flush();

for($i=0;$i < $profiles_ar['reach']; $i++)
{
   sleep(1);
}

echo "finshed: ".$i;

ob_flush();

flush();

ob_end_flush();

这会反复强制循环的第一次迭代输出并最终启动。