搜索

首页  >  问答  >  正文

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次传输才能发完一组数据...而且可行性还不确定
请问各位大大,你们在开发中遇到这种问题是怎么处理的?
在线等。。。

迷茫迷茫2743 天前850

全部回复(5)我来回复

  • PHP中文网

    PHP中文网2017-05-27 17:44:31

    雷雷

    回复
    0
  • phpcn_u1582

    phpcn_u15822017-05-27 17:44:31

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

    回复
    0
  • 滿天的星座

    滿天的星座2017-05-27 17:44:31

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

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

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

    回复
    0
  • 仅有的幸福

    仅有的幸福2017-05-27 17:44:31

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

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

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

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

    回复
    0
  • 伊谢尔伦

    伊谢尔伦2017-05-27 17:44:31

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

    回复
    0
  • 取消回复