Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中处理大量数据而无需浏览器超时_Php_Mysql_Codeigniter_Codeigniter 2 - Fatal编程技术网

在PHP中处理大量数据而无需浏览器超时

在PHP中处理大量数据而无需浏览器超时,php,mysql,codeigniter,codeigniter-2,Php,Mysql,Codeigniter,Codeigniter 2,我有很多手机号码,大约50000个。我正在尝试使用第三方API处理并向这些号码发送批量短信,但浏览器会冻结几分钟。我在寻找更好的选择 数据处理包括检查移动电话号码类型(如CDMA)、为所有号码分配唯一ID以供进一步参考、检查网络/国家唯一费用等 我曾想过将数据库中的数据排队,并使用cron每分钟批量发送大约5k,但如果有很多消息,这将需要时间。我的其他选择是什么 我正在XAMPP服务器上使用Codeigniter 2。我将编写两个脚本: 文件index.php: <iframe src="

我有很多手机号码,大约50000个。我正在尝试使用第三方API处理并向这些号码发送批量短信,但浏览器会冻结几分钟。我在寻找更好的选择

数据处理包括检查移动电话号码类型(如CDMA)、为所有号码分配唯一ID以供进一步参考、检查网络/国家唯一费用等

我曾想过将数据库中的数据排队,并使用cron每分钟批量发送大约5k,但如果有很多消息,这将需要时间。我的其他选择是什么


我正在XAMPP服务器上使用Codeigniter 2。

我将编写两个脚本:

文件
index.php

<iframe src="job.php" frameborder="0" scrolling="no" width="1" height="1"></iframe>
<script type="text/javascript">
    function progress(percent){
        document.getElementById('done').innerHTML=percent+'%';
    }
</script><div id="done">0%</div>
set_time_limit(0);                   // ignore php timeout
ignore_user_abort(true);             // keep on going even if user pulls the plug*
while(ob_get_level())ob_end_clean(); // remove output buffers
ob_implicit_flush(true);             // output stuff directly
// * This absolutely depends on whether you want the user to stop the process
//   or not. For example: You might create a stop button in index.php like so:
//     <a href="javascript:window.frames[0].location='';">Stop!</a>
//     <a href="javascript:window.frames[0].location='job.php';">Start</a>
// But of course, you will need that line of code commented out for this feature to work.

function progress($percent){
    echo '<script type="text/javascript">parent.progress('.$percent.');</script>';
}

$total=count($mobiles);
echo '<!DOCTYPE html><html><head></head><body>'; // webkit hotfix
foreach($mobiles as $i=>$mobile){
    // send sms
    progress($i/$total*100);
}
progress(100);
echo '</body></html>'; // webkit hotfix

我假设这些数字在数据库中,如果是这样的话,您应该添加一个名为ISENT的新列(或任何您喜欢的列)

您键入的下一段应该排队,可能在晚上/每周/适当的时候完成。除非你也有特定的原因,否则不应该按需批量完成。您甚至可以向数据库中添加一列以查看上次检查的时间,这样,如果某个数字在至少X天内未被检查,则可以根据需要对该数字执行检查

数据处理包括检查移动电话号码类型(如CDMA)、为所有号码分配唯一ID以供进一步参考、检查网络/国家唯一费用等

但这仍然会让你回到同样的问题上,如何一次处理50000个数字。既然您提到了cron作业,我假设您对服务器具有SSH访问权限,这意味着您不需要浏览器。这些cron作业可以通过以下命令行执行:

/usr/bin/php/home/username/example.com/myscript.php

我的建议是每10分钟通过cron一次处理1000个数字,并确定这需要多长时间,然后将其保存到数据库中。因为您使用的是cron作业,所以这些短信似乎不是时间敏感的短信,所以它们可以传播。一旦知道该脚本运行50次(50*1000=50k)需要多长时间,就可以更新cron作业以增加/减少运行频率

$time_start = microtime(true);
set_time_limit(0);

function doSendSMS($phoneNum, $msg, $blah);

$time_end = microtime(true);
$time = $time_end - $time_start;
saveTimeRequiredToSendMessagesInDB($time);
另外,您可能已经注意到设置了时间限制(0),这将告诉PHP在默认的30秒后不要超时。如果您能够修改PHP.ini文件,则无需输入这行代码。即使您能够编辑PHP.ini文件,我仍然建议不要更改此功能,因为您可能希望其他页面超时


Cronjob将是您的最佳选择,如果您目前唯一的问题是浏览器超时,我不明白为什么它会比在浏览器中执行它花费更长的时间


如果你坚持通过浏览器来做,那么另一个解决方案是按1000的批次做,并重定向到同一个脚本,但是参考它最后一次在$$GET变量中得到的位置。

如果这不是一次性的情况,请考虑一个更好的解决方案。 您基本上想要的是一个队列,您的浏览器绑定进程可以写入该队列,并且超过1-N个工作进程可以读取和更新该队列

将工作放入队列应该是相当便宜的—可能是一堆简单的INSERT语句到SQL RDBMS

然后您可以有一个或两个守护进程(或100个,分布在多个服务器上)从队列中读取和处理数据。在这里,您需要小心,避免两个工人承担相同的任务,但这并不难编码

因此,浏览器绑定的工作流是:单击某个按钮,使一堆东西添加到队列中,然后重定向到某个“队列状态”界面,用户可以在该界面上观看系统仔细检查他们的所有工作

像这样的系统很好,因为它很容易横向扩展


编辑:Christian Sciberras的答案是朝这个方向的,除了浏览器最终会左右移动(它会增加队列,然后驱动工作进程)

回答得很好,非常感谢。//即使用户拔掉插头,也要继续运行(非常有趣)@Christian该解决方案在FireFox&IE上运行得更好,但是google Chrome冻结了,还有其他出路吗?Safari Webkit(也使用din Chrome)在PHP进度功能上有一些问题。我找到了解决办法,我会给你回复的。。。编辑:修复。@Christian Sciberras您能解释一下“修复程序”吗?Chrome是否只需要有效的doctype和布局?伟大的答案,虽然,将书签这@Christian它工作得很糟糕,我将使用css并使进度条看起来干净。多谢各位