$arr[$line]=explode("\t",$str);
改成
$arr[$line]=explode("\r\n",$str);
字符串没有被分割,导致数组元素大小超出界限

解决方案 »

  1.   

    // $arr[$line]=explode("\t",$str);  //把每行分解到数组
    $arr[$line]=explode("\n",$str);
      

  2.   

    谢谢楼上的两位,有点我没有说得很清楚,是要把每行以\t分隔的字段分解到数组,因此以"\n"分隔也还没有根本解决问题,我把fgets($str,4096)理解为读文件直到遇到换行为止或字节数大于4096为止,因此读一次不会有多个"\n"后来把
    $arr[$line]=explode("\t",$str);
    改为:
    $arr[$line]=$str;       //这样又没有问题了,但没达到我的目的又改为:
    $fields=explode("\t",$str);
    $arr[$line]=$fields;
    这样换了一个方式,问题还是依旧
    只要用到二维数组就出问题请问使用二维数组有什么样的限制呢?应该注意些什么?
      

  3.   

    Fatal error: Allowed memory size of 20971520 bytes exhausted (tried to allocate 4097 bytes)
    允许的20971520字节内存已用完,无法申请到4097字节内存你可以适当减小fgets需要的缓冲区,比如1024。
    实际上4096字节长的行是极少存在的,你知道4096字节的文字是什么概念吗?一页16开5号字的文字才1500字节左右。另外,把一兆多的文字都装入内存并不是明智的做法。你可以用一行才装一行嘛
      

  4.   

    非常感谢xuzuning(唠叨)!
      可不可以增加内存的限制呢?虽然我的物理内存的容量不是很大,但是Linix系统应该可以用磁盘的交换分区来模拟内存,我的交换区可以分得比较大。
      读如内存的目的是为了引用方便,如果不做成二维表,在引用的时候要做特殊处理,很烦琐  说起我这样做的原因,其实也是万不得已
      我在Linux系统上要用PHP查询Windows上的数据库SQLSERVER 2k,弄了N久,都没法达到实用程度,安装了驱动freetds,用驱动提供的tsql命令可以查询MSSQL,可以显示汉字也可以以汉字为条件进行查询,看起来是比较完美的,PHP要通过freetds直接使用MSSQL,要重新编译PHP,PHP编译完成后,与原来的其他相关的依赖包不能整合,如果全靠自己手工去配置和编译,还没有这个能力,因此也无法实现。
      又用php-->odbc-->freetds-->mssql的方式来测试,配置好以后,PHP可以查询mssql,可以正常显示汉字,但是不能用汉字作为查询条件,因此没有实用价值。
      能想到的方案都试过了,始终不能解决汉字的问题  后来想到tsql命令很正常,就在php里面通过下面的方式来间接查询,算是有点另类了
    function ms_sql($ms_server,$database,$sql,$user="sa",$password=""){
      $str="echo -e \"use $database;$sql\ngo;quit";   //输出SQL语句到标准输出
      $str.="| tsql $ms_server -U $user -P '$password'"; //查询命令通过管道从标准输入去得SQL语句并把查询结果输出到标准输出
      if($fd=popen($str,"r")){
        where($str=fgets($fd,1024)){
          //这里把查询的结果保存到二维数组中,最后作为结果返回调用程序
          };
        pclose($fd);
        };
      return $query;
      }看看xuzuning(唠叨)能不能提供些指点,让我能够达到实用程度,如果实在没办法,我就打算查询结果存放在临时文件里,要去查询数据时就操作临时文件,但这是下下策了
      

  5.   

    1、增加物理内存可能是较好的解决办法
    2、交换区不能解决内存问题,底层文件函数必须使用物理内存
    3、根据你的描述,你可以用fgetcsv函数来替换fgets函数,这样多出来的就是数组,而不需要再切割了。这样可以节省一半内存
    4、不过这样大的数据文件还是保存到临时文件比较好。由于是查询结果,所以是有序的。你只要在写入临时文件时做一个索引文件,记录每一行在临时文件的位置。以后用二分法查找,最坏也只需移动文件指针16次(对于116029行)
      

  6.   

    $line=0;    //行数
    if ($handle = @fopen("inputfile.txt", "r")) {
        while (!feof($handle)) {
            /*$buffer = fgets($handle, 4096);
            echo $buffer . "<br>";*/
    $arr[$line]= fgets($handle, 4096);//直接读取的是每行的数据
    $line++;
        }
        fclose($handle);
    }
    else
    {
    echo "文件未打开\n";
    }
    var_dump($arr);
      

  7.   

    我看楼主的问题,换用file函数会不会好一点?