Как извлечь данные из файла csv в PHP

У меня есть файл 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" ... Есть ли какой-нибудь элегантный способ сделать это?


person liysd    schedule 10.05.2010    source источник
comment
Используйте explode вместо split   -  person John Rasch    schedule 10.05.2010
comment
Используйте инструмент, созданный для этой цели (например, fgetcsv, чтобы назвать один) вместо explode   -  person salathe    schedule 10.05.2010
comment
Один из методов (хотя fgetcsv лучше) состоит в том, чтобы соединить соседние поля до тех пор, пока объединенное поле не закончится кавычкой, если поле начинается с кавычки...   -  person Gert van den Berg    schedule 17.05.2018


Ответы (12)


Вы можете использовать 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);
}
person Matt    schedule 10.05.2010
comment
Есть ли аналогичная функция для линии? - person liysd; 10.05.2010
comment
Да, fgets получит всю строку. - person Mitch Dempsey; 10.05.2010
comment
@liysd - Да, вы можете передать строку в str_getcsv, однако это доступно только в PHP 5.3+. Однако в разделе комментариев есть замена. - person Matt; 10.05.2010
comment
Я имею в виду, что вводится строка, а не дескриптор файла - person liysd; 10.05.2010
comment
Если строка вводная, а не из файла, уточните это в вопросе. - person salathe; 10.05.2010
comment
Новые версии могут иметь 0 вместо секунды (необязательный параметр), для неограниченной длины строки - person Gert van den Berg; 17.05.2018

В дополнение к предложению Мэтта, вы также можете использовать 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

person Gordon    schedule 10.05.2010

вот также простой способ прочитать CSV-файл.

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

вы можете прочитать данные, используя следующую функцию.

  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/

person Liz Eipe C    schedule 02.11.2016

Возможно, мой код решит вашу проблему:

// 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
        )

)
person arraksis    schedule 09.09.2018

Предположим, у вас есть функция для одних и тех же вещей. Тогда она должна выглядеть так:

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);
person Harikesh Yadav    schedule 10.09.2015
comment
Ммм... это удаляет исходный CSV-файл, что должно быть неправильно, например, в 99% случаев. - person ftrotter; 14.10.2017
comment
Вы должны читать код. Я редактирую код для собственного использования stackoverflow.com/a/59472196/5714639 - person Lukáš Kříž; 24.12.2019

Вы можете использовать что-то вроде 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/

person Emil M    schedule 10.10.2017

Если вы хотите сохранить индекс (первую строку) для многомерного массива результатов, вы можете использовать:

$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);
}
person powtac    schedule 11.04.2018

Я создал приложение для извлечения данных из файла 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 : [email protected]
*/
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
person Riss    schedule 01.09.2018

Верните массив отображения 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;
  }
person Matoeil    schedule 20.05.2019


Только что создал функцию, которая извлекает данные из файла .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

person Crimin4L    schedule 25.05.2021