PHP处理超长数据内存限制问题
迷茫
迷茫 2017-05-27 17:42:31
[PHP讨论组]

目前存在多台雷达设备,对一定区域范围进行扫描,扫描后将返回约140万个点(每个点包含4个属性)的数据。
然后雷达设备将数据拼接成以 , 分隔的字符串:"x1,y1,a1,p1,x2,y2,a2,p2......x1400000,y1400000,a1400000,p1400000"
这个字符串大小应该有几十兆、不到100兆吧。
PHP代码是这样处理的:

$num=$_POST['num'];//点的总数量
$str=$_POST['str'];//点的4个属性组成的字符串
$str_arr=expload(',',$str);//将字符串转换为数组

//将数组转换成json字符串
$point=array();
for($n=1;$n<=$num;$n++){
    $x=$str_arr[$n*4-4];
    $y=$str_arr[$n*4-3];
    $a=$str_arr[$n*4-2];
    $p=$str_arr[$n*4-1];
    $point[]=array("x"=>$x,"y"=>$y,"a"=>$a,"$p"=>$p);
}
$json_str=json_encode($point);

//将json字符串保存在".txt"文件中
$handle=fopen("./1.txt","w");
fwrite($handle, $json_str);
fclose($handle);

//返回请求成功信息
echo "ask=1&cmd=3";
exit;

对于内存消耗我不太懂,也是第一次处理这么大的数据
当雷达传输的数据只有11W组点(约3MB数据)时,我这边才能顺利接收并且进行处理
当数据再大一点之后就提示内存限制128M
我自己去网上查了一些方法,大部分都是叫改php.ini文件中memory_limit=-1
可是改了之后仍然无法传输
目前跟雷达端商量的是他每次最多给我传10W组点,然后再多个一个参数本次传输还剩多少点,PHP接收到后作为返回值给他,他再回调继续给我发,但是这样算下来,一共要进行14~15次传输才能发完一组数据...而且可行性还不确定
请问各位大大,你们在开发中遇到这种问题是怎么处理的?
在线等。。。

迷茫
迷茫

业精于勤,荒于嬉;行成于思,毁于随。

全部回复(5)
PHP中文网
ini_set('memory_limit', '500M'); //内存限制
set_time_limit(0); //执行超时,0代表无限等待
phpcn_u1582

题主 gzip 开启了没? 这种纯 JSON 数据,开启了以后压缩率很高的。改大了内存限制以后,网络连接也可能会超时的。

滿天的星座
  1. web服务器接收Body有长度限制,超长不能接收, 比如nginx-client_max_body_size

  2. web模式下采用分批传输是比较好的方案

  3. 更好的方式是用socket二进制传输, 没有web模式下的各种限制, 效率较高

仅有的幸福

首先你这字符串占用内存就很大了,你再转换为数组处理占用内存会非常大的。

看你的需求,最后是转换为json存到文件,json也是字符串,为何不直接字符串处理呢。

如果是php7的话不能使用preg_replace,需要换成preg_replace_callback来处理

$str=$_POST['str'];//点的4个属性组成的字符串
$json_str = '['.substr(preg_replace('/([^,]+),([^,]+),([^,]+),([^,]+),/iU','{"x":"$1","y":"$2","a":"$3","p":"$4"},',$str.','),0,-1).']';
//将json字符串保存在```.txt```文件中
$handle=fopen("./1.txt","w");
fwrite($handle, $json_str);
fclose($handle);
伊谢尔伦

内存限制开大,还有post的数据量也开大就可以了。。基本上几百兆处理起来是没问题的

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号