Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/260.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解析CSV文件_Php_Csv_Fgetcsv - Fatal编程技术网

如何使用PHP解析CSV文件

如何使用PHP解析CSV文件,php,csv,fgetcsv,Php,Csv,Fgetcsv,假设我有一个包含以下内容的.csv文件: "text, with commas","another text",123,"text",5; "some without commas","another text",123,"text"; "some text with commas or no",,123,"text"; 如何通过PHP解析内容?只需使用函数解析CSV文件即可 $row=1; if($handle=fopen(“test.csv”、“r”)!==FALSE)

假设我有一个包含以下内容的
.csv
文件:

 "text, with commas","another text",123,"text",5; 
 "some    without commas","another text",123,"text";
 "some text with  commas or no",,123,"text"; 

如何通过PHP解析内容?

只需使用函数解析CSV文件即可

$row=1;
if($handle=fopen(“test.csv”、“r”)!==FALSE){
while(($data=fgetcsv($handle,1000,“,”)!==FALSE){
$num=计数($data);
echo“$num字段位于第$row行:

\n”; $row++; 对于($c=0;$c<$num;$c++){ echo$data[$c]。“
\n”; } } fclose($handle); }
我一直在寻找同样的东西,但没有使用一些不受支持的PHP类。Excel CSV并不总是使用引号分隔符,而是使用“”来转义引号,因为该算法可能是在80年代或其他时候提出的。在查看了PHP.NET评论部分中的几个.csv解析器之后,我看到了一些甚至使用回调或评估代码的解析器,它们要么无法正常工作,要么根本无法工作。因此,我为此编写了自己的例程,它们在最基本的PHP配置中工作。数组键可以是数字,也可以按标题行中给定的字段命名。希望这有帮助

    function SW_ImplodeCSV(array $rows, $headerrow=true, $mode='EXCEL', $fmt='2D_FIELDNAME_ARRAY')
    // SW_ImplodeCSV - returns 2D array as string of csv(MS Excel .CSV supported)
    // AUTHOR: tgearin2@gmail.com
    // RELEASED: 9/21/13 BETA
      { $r=1; $row=array(); $fields=array(); $csv="";
        $escapes=array('\r', '\n', '\t', '\\', '\"');  //two byte escape codes
        $escapes2=array("\r", "\n", "\t", "\\", "\""); //actual code

        if($mode=='EXCEL')// escape code = ""
         { $delim=','; $enclos='"'; $rowbr="\r\n"; }
        else //mode=STANDARD all fields enclosed
           { $delim=','; $enclos='"'; $rowbr="\r\n"; }

          $csv=""; $i=-1; $i2=0; $imax=count($rows);

          while( $i < $imax )
          {
            // get field names
            if($i == -1)
             { $row=$rows[0];
               if($fmt=='2D_FIELDNAME_ARRAY')
                { $i2=0; $i2max=count($row);
                  while( list($k, $v) = each($row) )
                   { $fields[$i2]=$k;
                     $i2++;
                   }
                }
               else //if($fmt='2D_NUMBERED_ARRAY')
                { $i2=0; $i2max=(count($rows[0]));
                  while($i2<$i2max)
                   { $fields[$i2]=$i2;
                     $i2++;
                   }
                }

               if($headerrow==true) { $row=$fields; }
               else                 { $i=0; $row=$rows[0];}
             }
            else
             { $row=$rows[$i];
             }
    
            $i2=0;  $i2max=count($row); 
            while($i2 < $i2max)// numeric loop (order really matters here)
            //while( list($k, $v) = each($row) )
             { if($i2 != 0) $csv=$csv.$delim;

               $v=$row[$fields[$i2]];

               if($mode=='EXCEL') //EXCEL 2quote escapes
                    { $newv = '"'.(str_replace('"', '""', $v)).'"'; }
               else  //STANDARD
                    { $newv = '"'.(str_replace($escapes2, $escapes, $v)).'"'; }
               $csv=$csv.$newv;
               $i2++;
             }

            $csv=$csv."\r\n";

            $i++;
          }

         return $csv;
       }

    function SW_ExplodeCSV($csv, $headerrow=true, $mode='EXCEL', $fmt='2D_FIELDNAME_ARRAY')
     { // SW_ExplodeCSV - parses CSV into 2D array(MS Excel .CSV supported)
       // AUTHOR: tgearin2@gmail.com
       // RELEASED: 9/21/13 BETA
       //SWMessage("SW_ExplodeCSV() - CALLED HERE -");
       $rows=array(); $row=array(); $fields=array();// rows = array of arrays

       //escape code = '\'
       $escapes=array('\r', '\n', '\t', '\\', '\"');  //two byte escape codes
       $escapes2=array("\r", "\n", "\t", "\\", "\""); //actual code

       if($mode=='EXCEL')
        {// escape code = ""
          $delim=','; $enclos='"'; $esc_enclos='""'; $rowbr="\r\n";
        }
       else //mode=STANDARD 
        {// all fields enclosed
          $delim=','; $enclos='"'; $rowbr="\r\n";
        }

       $indxf=0; $indxl=0; $encindxf=0; $encindxl=0; $enc=0; $enc1=0; $enc2=0; $brk1=0; $rowindxf=0; $rowindxl=0; $encflg=0;
       $rowcnt=0; $colcnt=0; $rowflg=0; $colflg=0; $cell="";
       $headerflg=0; $quotedflg=0;
       $i=0; $i2=0; $imax=strlen($csv);   

       while($indxf < $imax)
         {
           //find first *possible* cell delimiters
           $indxl=strpos($csv, $delim, $indxf);  if($indxl===false) { $indxl=$imax; }
           $encindxf=strpos($csv, $enclos, $indxf); if($encindxf===false) { $encindxf=$imax; }//first open quote
           $rowindxl=strpos($csv, $rowbr, $indxf); if($rowindxl===false) { $rowindxl=$imax; }

           if(($encindxf>$indxl)||($encindxf>$rowindxl))
            { $quoteflg=0; $encindxf=$imax; $encindxl=$imax;
              if($rowindxl<$indxl) { $indxl=$rowindxl; $rowflg=1; }
            }
           else 
            { //find cell enclosure area (and real cell delimiter)
              $quoteflg=1;
              $enc=$encindxf; 
              while($enc<$indxl) //$enc = next open quote
               {// loop till unquoted delim. is found
                 $enc=strpos($csv, $enclos, $enc+1); if($enc===false) { $enc=$imax; }//close quote
                 $encindxl=$enc; //last close quote
                 $indxl=strpos($csv, $delim, $enc+1); if($indxl===false)  { $indxl=$imax; }//last delim.
                 $enc=strpos($csv, $enclos, $enc+1); if($enc===false) { $enc=$imax; }//open quote
                 if(($indxl==$imax)||($enc==$imax)) break;
               }
              $rowindxl=strpos($csv, $rowbr, $enc+1); if($rowindxl===false) { $rowindxl=$imax; }
              if($rowindxl<$indxl) { $indxl=$rowindxl; $rowflg=1; }
            }

           if($quoteflg==0)
            { //no enclosured content - take as is
              $colflg=1;
              //get cell 
             // $cell=substr($csv, $indxf, ($indxl-$indxf)-1);
              $cell=substr($csv, $indxf, ($indxl-$indxf));
            }
           else// if($rowindxl > $encindxf)
            { // cell enclosed
              $colflg=1;
     
             //get cell - decode cell content
              $cell=substr($csv, $encindxf+1, ($encindxl-$encindxf)-1);

              if($mode=='EXCEL') //remove EXCEL 2quote escapes
                { $cell=str_replace($esc_enclos, $enclos, $cell);
                }
              else //remove STANDARD esc. sceme
                { $cell=str_replace($escapes, $escapes2, $cell);
                }
            }

           if($colflg)
            {// read cell into array
              if( ($fmt=='2D_FIELDNAME_ARRAY') && ($headerflg==1) )
               { $row[$fields[$colcnt]]=$cell; }
              else if(($fmt=='2D_NUMBERED_ARRAY')||($headerflg==0))
               { $row[$colcnt]=$cell; } //$rows[$rowcnt][$colcnt] = $cell;

              $colcnt++; $colflg=0; $cell="";
              $indxf=$indxl+1;//strlen($delim);
            }
           if($rowflg)
            {// read row into big array
              if(($headerrow) && ($headerflg==0))
                {  $fields=$row;
                   $row=array();
                   $headerflg=1;
                }
              else
                { $rows[$rowcnt]=$row;
                  $row=array();
                  $rowcnt++; 
                }
               $colcnt=0; $rowflg=0; $cell="";
               $rowindxf=$rowindxl+2;//strlen($rowbr);
               $indxf=$rowindxf;
            }

           $i++;
           //SWMessage("SW_ExplodeCSV() - colcnt = ".$colcnt."   rowcnt = ".$rowcnt."   indxf = ".$indxf."   indxl = ".$indxl."   rowindxf = ".$rowindxf);
           //if($i>20) break;
         }

       return $rows;
     }
函数SW\u introdecsv(数组$rows,$headerrow=true,$mode='EXCEL',$fmt='2D\u FIELDNAME\u array')
//SW_内爆csv-以csv字符串形式返回2D数组(支持MS Excel.csv)
//作者:tgearin2@gmail.com
//发布日期:2013年9月21日测试版
{$r=1;$row=array();$fields=array();$csv=”“;
$escapes=array('\r'、'\n'、'\t'、'\\'、'\');//两字节转义码
$escapes2=数组(“\r”、“\n”、“\t”、“\\”、“\\”);//实际代码
如果($mode=='EXCEL')//escape code=“”
{$delim=',';$enclose='”;$rowbr=“\r\n”;}
else//mode=标准所有封闭字段
{$delim=',';$enclose='”;$rowbr=“\r\n”;}
$csv=“”;$i=-1;$i2=0;$imax=count($rows);
而($i<$imax)
{
//获取字段名
如果($i==-1)
{$row=$rows[0];
如果($fmt=='2D\u字段名\u数组')
{$i2=0;$i2max=count($row);
while(列表($k,$v)=每个($row))
{$fields[$i2]=$k;
$i2++;
}
}
else//if($fmt='2D\u编号\u数组')
{$i2=0;$i2max=(count($rows[0]);

而($i2的答案要短一点,因为:

我喜欢这个

$data = str_getcsv($CsvString, "\n"); //parse the rows
foreach ($data as &$row) {
    $row = str_getcsv($row, "; or , or whatever you want"); //parse the items in rows 
    $this->debug($row);
}

在我的例子中,我将通过web服务获取csv,因此通过这种方式,我不需要创建文件。但是,如果需要使用文件进行解析,只需要将csv文件作为字符串传递到数组中即可

$csv = array_map('str_getcsv', file('data.csv'));

刚刚发现了一种在解析时获取索引的简便方法。我的脑子被炸了

$handle = fopen("test.csv", "r");
for ($i = 0; $row = fgetcsv($handle ); ++$i) {
    // Do something will $row array
}
fclose($handle);


来源:

你基本上是在问,是否有比股票全局函数方法更好的面向对象方法来处理w/CSV解析。我要说的是重写这个问题,因为这听起来不像是解析CSV的问题。@quickshiftin很抱歉,没关系,我只是说……如果你想要一个类就可以了(我在工作中对它做了一些调整…)需要注意的是,该函数不能正确处理CSV中的引号。特别是,它不能处理wikipedia中的示例:有一个开放的bug,但它已被关闭为“不会修复”。请注意,如果实际值中有任何换行符(而不是每个CSV行末尾的行分隔符),则该函数不起作用,因为
file
函数在换行符上拆分,并且不知道CSV用于包含字段值的引号。如何使用不同的分隔符?(;而不是,)使用以下方法解决换行问题:数组映射('str_getcsv',file('data.CSV',file_IGNORE_new_line | file_SKIP_EMPTY_line));你知道,给各自的作者评分是很好的:@Maxim Kovalevsky,如何跳过标题或第一行请注意,如果实际值中有任何换行符(而不是每行末尾的行分隔符),则这不起作用,因为
文件
函数在换行符上拆分,并且不知道CSV用于包含字段值的引号。@JordanLev那么您推荐什么?@Julix use。如果您知道导入的数据在单个值中永远不会有换行符,那么这个较短的版本很好,但其他更健壮的解决方案是值得的额外的代码行。我在保存到CSV之前进行了编码,并在阅读时进行解码——这确保了没有断行,对吗?——或者它完全丢失了它们(URL编码中会有断行吗?)这个答案非常适用于新行,并使用了php文件函数的魔力。ThanksOur服务器有PHP5.2.9,我无法访问str_getcsv,因为这个原因。另一方面,fgetcsv的日期一直到PHP4,所以这很有帮助。谢谢。只是想知道为什么使用for循环而不是while循环?@valerie我几乎总是需要一个in循环解析CSV时使用dex。for循环提供的索引没有单独的声明和递增符。这对我来说不正常。例如,这:
aaa,bbb,“ccc\nddd”,eee
被解析为两行(而不是所需的一行),而不是一行。似乎
出现在字段内部时(而不是在其开始或结束时)不会被识别为存储模块。因此,
$data=str\u getcsv(..)
可以替换为
$data=explode(..)
,我猜这更有效,更能传达意图。。。
$csv = array_map('str_getcsv', file('data.csv'));
$handle = fopen("test.csv", "r");
for ($i = 0; $row = fgetcsv($handle ); ++$i) {
    // Do something will $row array
}
fclose($handle);