【问题标题】:reading large csv file contain comma with php用php读取包含逗号的大型csv文件
【发布时间】:2019-01-02 03:32:13
【问题描述】:

我有需要用 php 读取的 csv 文件。我使用了 2 种方法,但主题有问题。

我使用的方法是: 1- file_get_contents 2-fgetcsv 让我们解释一下 csv 文件。关于文件的问题是字段包含用于分隔符的逗号及其困扰。 第一种方法很快,但字段中的逗号使其无法正常工作,如数字分隔符 14,200 。我用一个名为固定数字的函数修复了它。但是仍然有包含逗号的随机文本并且不遵循我可以修复它们的任何规则 大 csv 的第二种方法非常慢,我无法看到它的工作原理 第一种方法的代码如下:

$myFile = file_get_contents($file);
$lines = explode("\r\n",$myFile);//file to an array


while($counter <= count($lines)){
$data=$lines[$counter]; 

$tmp=fixnumbers($data);
$tmp=eregi_replace('"', '',$tmp);
$tmp=explode(',',$tmp); 


if(count($tmp)> 0 ){
$newdata[$datacounter]=$tmp;//explode('*0*',$data);
$datacounter++;
}
$counter++;
}

第二种方法在这里:

$handle= fopen($file,"r");
    $row=1;
       while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
      $num = count($data);

      for ($c=0; $c < $num; $c++) {
          $mydata[$row][$c]=$data[$c] . "<br />\n";
      }$row++;
   }

print "<div class=\"longList\"><pre>";  
        print_r($mydata);
print "</pre></div>";
    fclose($file);


}

【问题讨论】:

  • 你能贴几行你的csv文件吗?如果一个数字字段中有逗号,那么它应该是一个文本字段并被引用,fgetcsv 应该正确处理。
  • 这是一个示例文件,但不是英文的:rapidgator.net/file/ef4f99844b702a8fa3871cc7acaee4af/…
  • ang fgetcsv 在我的经验中比 file_get_content 慢
  • 我看过的几行似乎引号被正确应用了。 fgetcsv 应该可以为您处理。
  • 我用 fgetcsv 运行第二个代码并使用这个文件。但它需要超过 10 分钟,仍然没有输出或最大 php 执行时间错误

标签: php csv


【解决方案1】:

所以我等待下载文件,抓取前 5 条记录,然后复制/粘贴 PHP 手册中的 fgetcsv 示例。

前 5 条记录 - https://termbin.com/23ti - 保存为“sm_file.csv”

<?php

if (($handle = fopen("sm_file.csv", "r")) !== FALSE) {
    $data=array();
    $num=0;
    while (($data[] = fgetcsv($handle, 1000, ",")) !== FALSE) {
            $num++;
    }
    fclose($handle);
    print_r($data);
}

?>



[0] => Array
    (
        [0] => از تاريخ وصل 01/07/1397 - با برنامه
        [1] => تاريخ گزارش: 29/09/1397
        [2] => شماره گزارش: (3-5)
        [3] => صفحه 1
        [4] => گزارش قطع و وصل فيدرهاي فشار متوسط (نمونه 3)
        [5] => ملاحظات
        [6] => شرايط جوي
        [7] => عملكرد ريكلوزر
        [8] => رله عامل
        [9] => خاموشي (MWh)
        [10] => بار فيدر (A)
        [11] => مدت قطع
        [12] => زمان وصل
        [13] => تاريخ وصل
        [14] => زمان قطع
        [15] => تاريخ قطع
        [16] => نوع اشكال بوجود آمده
        [17] => فيدر فشار متوسط
        [18] => پست فوق توزيع
        [19] => شماره پرونده
        [20] => رديف
        [21] =>  ناحيه اسالم
        [22] => 
        [23] => آفتابي
        [24] => ندارد
        [25] => ندارد
        [26] => 0.21
        [27] => 3
        [28] => 132
        [29] => 11:30
        [30] => 1397/07/04
        [31] => 09:18
        [32] => 1397/07/04
        [33] => جهت كار در حريم شبكه
        [34] => گيسوم
        [35] => اسا لم
        [36] => 96,042,429,972
        [37] => 1
        [38] => 61292.56
        [39] => جمع کل بار فيدر:
        [40] => 393.85
        [41] => جمع کل خاموشي:
        [42] => 92,725
        [43] => جمع مدت قطع:
    )

看起来数据元素 36 是您遇到的问题,您可以看到 fgetcsv 处理得很好,您只需在处理数据时将字符串转换为数字。只需去掉逗号。

<?php

if (($handle = fopen("sm_file.csv", "r")) !== FALSE) {
    $data=array();
    $num=0;
    while (($data[] = fgetcsv($handle, 1000, ",")) !== FALSE) {
        $data[(count($data)-1)][36]=str_replace(",","",$data[(count($data)-1)][36]);
    }
    fclose($handle);
    print_r($data);
}

?>

这给了

[36] => 96042429972

至于需要多长时间,你的2k条记录的完整文件

User time (seconds): 0.12
System time (seconds): 0.09
Percent of CPU this job got: 43%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.52
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 41820
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 2448
Voluntary context switches: 18
Involuntary context switches: 55
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0

在配备 8GB 内存的普通 i5 上。没有发现任何问题。

【讨论】:

  • 感谢您的回复。我用逗号解决了数字问题,但是有些带逗号的文本我无法使用 file_get_content 方法处理。我也不知道为什么 fgetcsv 需要很长时间才能获得输出。上次我使用 $array = array_map('str_getcsv', file($file));。它似乎工作正常,但我肯定需要在许多 csv 上对其进行测试。无论如何,再次感谢你
  • 我修改了脚本并运行了大约 1500 条记录并插入 mysql 数据库的脚本。大约需要 2 分钟。我担心超过 10000 条记录的 csv。我的笔记本电脑是 i5 和 4gb 内存。我将 php 内存限制增加到 512 mb。你能建议一种方法来减少运行时间或单独执行而不需要手动拆分 csv。“我想运行这个脚本的工作电脑是双核的”,但运行时间就像我的笔记本电脑一样。我认为它与cpu无关。但我不知道如何提高运行和插入数据库的速度
  • 如果我打印输出它甚至需要更长的时间
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 2011-01-11
  • 1970-01-01
  • 2017-03-17
  • 2013-07-29
  • 2023-02-21
相关资源
最近更新 更多