【问题标题】:How to extract data from csv file in PHP如何在 PHP 中从 csv 文件中提取数据
【发布时间】:2011-02-17 19:48:06
【问题描述】:

我有一个 csv 文件,看起来像这样

$lines[0] = "text, with commas", "another text", 123, "text",5;
$lines[1] = "some without commas", "another text", 123, "text";
$lines[2] = "some text with commas or no",, 123, "text";

我想要一张桌子:

$t[0] = array("text, with commas", "another text", "123", "text","5");
$t[1] = array("some without commas", "another text", "123", "text");
$t[2] = array("some text, with comma,s or no", NULL , "123", "text");

如果我使用split($lines[0],","),我会得到"text" ,"with commas" ... 有什么优雅的方法吗?

【问题讨论】:

  • 使用explode 而不是split
  • 使用为此目的构建的工具(例如fgetcsv 来命名)而不是explode
  • 一种方法(虽然 fgetcsv 更好)是加入相邻的字段,直到合并的字段以引号结尾,如果字段以引号开头...

标签: php csv split


【解决方案1】:

您可以使用fgetcsv 解析CSV 文件,而不必担心自己解析它。

PHP 手册中的示例:

$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
        $num = count($data);
        echo "<p> $num fields in line $row: <br /></p>\n";
        $row++;
        for ($c=0; $c < $num; $c++) {
            echo $data[$c] . "<br />\n";
        }
    }
    fclose($handle);
}

【讨论】:

  • 一行有类似的功能吗?
  • 是的,fgets 会得到一整行。
  • @liysd - 是的,您可以将字符串传递给str_getcsv,但这仅在 PHP 5.3+ 中可用。不过,cmets 部分有一个替代品。
  • 我的意思是输入一行而不是文件句柄
  • 新版本可以为第二个(可选参数)传递“0”,以无限行长
【解决方案2】:

除了Matt's suggestion,还可以使用SplFileObject读入文件:

$file = new SplFileObject("data.csv");
$file->setFlags(SplFileObject::READ_CSV);
$file->setCsvControl(',', '"', '\\'); // this is the default anyway though
foreach ($file as $row) {
    list ($fruit, $quantity) = $row;
    // Do something with values
}

来源:http://de.php.net/manual/en/splfileobject.setcsvcontrol.php

【讨论】:

    【解决方案3】:

    这里也是获取读取csv文件的简单方法。

    $sfp = fopen('/path/to/source.csv','r'); $dfp = fopen('/path/to/destination.csv','w'); 而 ($row = fgetcsv($sfp,10000,",","")) { $goodstuff = ""; $goodstuff = str_replace("¦",",",$row[2]); $goodstuff .= "\n"; fwrite($dfp,$goodstuff); } fclose($sfp); fclose($dfp);

    【讨论】:

      【解决方案4】:

      您可以使用以下函数读取数据。

        function readCSV() {
          $csv = array_map('str_getcsv', file('data.csv'));
          array_shift($csv); //remove headers
      
      
      }
      

      http://www.pearlbells.co.uk/how-to-sort-a1a2-z9z10aa1aa2-az9az10-using-php/

      【讨论】:

        【解决方案5】:

        也许我的代码可以解决你的问题:

        // Parse all content from csv file and generate array from line.
        function csv_content_parser($content) {
          foreach (explode("\n", $content) as $line) {
            // Generator saves state and can be resumed when the next value is required.
            yield str_getcsv($line);
          }
        }
        // Get content from csv file.
        $content = file_get_contents('your_file.csv');
        // Create one array from csv file's lines.
        $data = array();
        foreach (csv_content_parser($content) as $fields) {
          array_push($data, $fields);
        }
        

        结果你有一个包含来自 csv 的所有值的数组。 它会是这样的:

        Array
        (
            [0] => Array
                (
                    [0] => text, with commas
                    [1] => another text
                    [2] => 123
                    [3] => text
                    [4] => 5
                )
        
            [1] => Array
                (
                    [0] => some without commas
                    [1] => another text
                    [2] => 123
                    [3] => text
                )
        
            [2] => Array
                (
                    [0] => some text, with comma,s or no
                    [1] =>  NULL 
                    [2] => 123
                    [3] => text
                )
        
        )
        

        【讨论】:

          【解决方案6】:

          假设你有一个创建相同事物的函数,那么它应该看起来像

          function csvtoarray($filename='', $delimiter){
          
              if(!file_exists($filename) || !is_readable($filename)) return FALSE;
              $header = NULL;
              $data = array();
          
              if (($handle = fopen($filename, 'r')) !== FALSE ) {
                  while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE)
                  {   
                      if(!$header){
                          $header = $row;
                      }else{
                          $data[] = array_combine($header, $row);
                      }
                  }
                  fclose($handle);
              }
              if(file_exists($filename)) @unlink($filename);
          
              return $data;
          }
          
          $data = csvtoarray('file.csv', ',');
          
          print_r($data);
          

          【讨论】:

          【解决方案7】:

          您可以使用类似https://github.com/htmlburger/carbon-csv 的东西来允许列映射:

          $csv = new \Carbon_CSV\CsvFile('path-to-file/filename.csv');
          $csv->set_column_names([
              0 => 'first_name',
              1 => 'last_name',
              2 => 'company_name',
              3 => 'address',
          ]);
          foreach ($csv as $row) {
              print_r($row);
          }
          

          下面代码的结果是这样的:

          Array
          (
              [0] => Array
                  (
                      [first_name] => John
                      [last_name] => Doe
                      [company_name] => Simple Company Name
                      [address] => Street Name, 1234, City Name, Country Name
                  )
              [1] => Array
                  (
                      [first_name] => Jane
                      [last_name] => Doe
                      [company_name] => Nice Company Name
                      [address] => Street Name, 5678, City Name, Country Name
                  )
          )
          

          另一个做同样事情(甚至更多)的库是http://csv.thephpleague.com/9.0/reader/

          【讨论】:

            【解决方案8】:

            当你想为多维结果数组保留索引(第一行)时,你可以使用:

            $delim      = ';';
            $csvFile    = file($csv_file);
            $firstline  = str_getcsv($csvFile[0], $delim);
            $data       = array();
            foreach ($csvFile as $line) {
                $line   = str_getcsv($line, $delim);
                $data[] = array_combine($firstline, $line);
            }
            

            【讨论】:

              【解决方案9】:

              我已经构建了一个从 CSV 文件中提取数据的应用程序,这个 php 应用程序用于为用户显示每日报价。

              github上的完整项目:365-quotes-php-csv.

              这也是我构建的应用程序的类代码

                <?php
              /*
              Main Class 
              please note :
              1- the CSV file must be comma separated (,) and each line must End with (;).
              2- Feel free to edit the all.CSV file and add all of your 366 New Quotes.
              3- don't change any thing specially the CSV file Location.
              ---------------------------------------------------------------------------
              RISS.WORK all copy rights reserved 2018
              please Don't Remove
              Github/RissWork
              Email : info@riss.work
              */
              class Quote{
              
                  //properties
                      private $_quote,$_allQuotes;
                      private static $_instance = null;
              
                  //Constructor
                      private function __construct(){
                          //Day Count
                          $dayCount = date(z);
              
                          if($this->readCsvAndGetQuote($dayCount)){
                              return $this->getQuote();
                          }else{
                              echo 'Error Cannot open the .CSV File';
                          }
                      }
              
              
              
              
              
                  //Methods
              
                  //get Instance
                  public function getInstance(){
                          if(!isset(self::$_instance)){
                              self::$_instance = new Quote();
                          }
                          return self::$_instance;
                      }//end of get Instance
              
              
              
              
                  //get daily Quote   
                  public function getQuote(){
                          return $this->_quote;
                      }//end of get Quote
              
              
              
              
                  //Read CSV
                  private function readCsvAndGetQuote($dayCount = 1 ){
              
                      if(($handel = fopen("csv/all.csv" , "r")) !== false){
                          $this->_allQuotes = fgetcsv($handel,1000000,';');
                          $this->_quote = explode(',',$this->_allQuotes[$dayCount]);
                          return true;
                      }
                      return false;
              
                  }//end of read CSV
              
              
              
              }//end of Class
              

              【讨论】:

                【解决方案10】:

                返回一个带有兴趣列的 php 映射数组:

                public function extractCSVDatas($file_uri) {
                    $AliasToSystemPathMappingArray = [];
                    if (($handle = fopen($file_uri, "r")) !== FALSE) {
                      $csv = array_map('str_getcsv', file($file_uri));
                
                      //remove header and choose columns among the list:
                      foreach((array_slice($csv,1)) as $line) {
                        list($id, $alias, $systemPath) = explode(';',$line[0]);
                        $AliasToSystemPathMappingArray[] = [$alias, $systemPath];
                      }
                      fclose($handle);
                    }
                    return $AliasToSystemPathMappingArray;
                  }
                

                【讨论】:

                  【解决方案11】:
                  /**
                   * @return mixed[]
                   */
                  public function csvToArray(string $delimiter, string $filename = ''): array
                  {
                      $data = [];
                      if (file_exists($filename) && is_readable($filename)) {
                          $header = null;
                  
                          if (($handle = fopen($filename, 'r')) !== false) {
                              while (($row = fgetcsv($handle, 1000, $delimiter)) !== false) {
                                  if (!$header) {
                                      $header = $row;
                                  } else {
                                      $data[] = array_combine($header, $row);
                                  }
                              }
                              fclose($handle);
                          }
                      }
                  
                      return $data;
                  }
                  

                  【讨论】:

                    【解决方案12】:

                    既然可以复杂,为什么一定要简单?

                    别开玩笑了,这里有一个使用 PHP 函数 str_getcsv() 的快速简单的解决方案

                    这是一个例子:

                    function parse_csv( $filename_or_text, $delimiter=',', $enclosure='"', $linebreak="\n" )
                    {
                        $return = array();
                        
                        if(false !== ($csv = (filter_var($filename_or_text, FILTER_VALIDATE_URL) ? file_get_contents($filename_or_text) : $filename_or_text)))
                        {
                            $csv = trim($csv);
                            $csv = mb_convert_encoding($csv, 'UTF-16LE');   
                            
                            foreach(str_getcsv($csv, $linebreak, $enclosure) as $row){
                                $col = str_getcsv($row, $delimiter, $enclosure);
                                $col = array_map('trim', $col);
                                $return[] = $col;
                            }
                        }
                        else
                        {
                            throw new \Exception('Can not open the file.');
                            $return = false;
                        }
                        
                        return $return;
                    }
                    

                    想象一下,您需要一个同时处理 URL 和逗号分隔文本的函数。这正是这样工作的功能。只需插入一个 CSV URL 或逗号分隔的文本,它就可以很好地工作。

                    【讨论】:

                      【解决方案13】:

                      刚刚创建了一个函数,它从 .csv 文件或 csv 格式的文本中提取数据,然后对其进行解析以便更方便地使用(假设第一行是列)。无论您想要/拥有多少行/列,只需简单地将函数指向文件位置/字符串,它就会返回结果!

                      function csvParse($input, $callback = false){
                          $results = [];
                          $raw_array = (is_file($input)) ? array_map('str_getcsv', file($input)) : array_map('str_getcsv', explode("\n", $input));
                          $array = array_splice($raw_array, 1, count($raw_array));
                          foreach($raw_array[0] as $c) $columns[] = $c;
                          foreach($array as $key0 => $val0) 
                              foreach($val0 as $key1 => $val1) 
                                  $results[$key0][$columns[$key1]] = $val1;
                          if(is_callable($callback)) call_user_func_array($callback, array($results));
                          else return $results;
                      }
                      
                      # Either One Would Work
                      $input = "dir/file.csv";
                      $input = "name,age,occupation,city\nCrimin4L,24,Programmer,New York\nMrAwesome,20,Gamer,Los Angeles";
                      
                      # Usage #1
                      $array = csvParse($input);
                      var_export($array);
                      
                      # Usage #2
                      csvParse($input, function($array){
                          var_export($array);
                      });
                      

                      输入:

                      name,age,occupation,city
                      Crimin4L,24,Programmer,New York
                      MrAwesome,20,Gamer,Los Angeles
                      

                      数组输出:

                      array (
                        0 => 
                        array (
                          'name' => 'Crimin4L',
                          'age' => '24',
                          'occupation' => 'programmer',
                          'city' => 'New York',
                        ),
                        1 => 
                        array (
                          'name' => 'MrAwesome',
                          'age' => '20',
                          'occupation' => 'gamer',
                          'city' => 'Los Angeles',
                        ),
                      )
                      

                      现场演示:https://ideone.com/Sa1aMO

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2018-05-20
                        • 2022-06-11
                        • 2018-06-23
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2021-09-26
                        相关资源
                        最近更新 更多