Как я могу получить общее количество строк в файле CSV с помощью PHP?

Как я могу получить общее количество строк в файле CSV с помощью PHP? Я использую этот метод, но могу заставить его работать правильно.

if (($fp = fopen("test.csv", "r")) !== FALSE) { 
  while (($record = fgetcsv($fp)) !== FALSE) {
      $row++;
  }

  echo $row;
}

person telexper    schedule 30.01.2014    source источник
comment
Такое решение должно работать, но проблема потенциально заключается в бите while(record...); Разбивается на пустые строки. Примечание; ни одно из предложенных решений, которые подсчитывают строки в файле, не являются надежными, поскольку они подсчитывают только строки, а не записи csv (которые могут содержать символы новой строки)   -  person Steve Horvath    schedule 04.12.2019


Ответы (10)


Вот еще один вариант использования file() для чтения всего файла в массив, автоматического анализа новых строк и т. д.:

$fp = file('test.csv');
echo count($fp);

Кроме того, начиная с PHP5, вы можете передать FILE_SKIP_EMPTY_LINES... для пропуска пустых строк, если хотите:

$fp = file('test.csv', FILE_SKIP_EMPTY_LINES);

Вручную: http://php.net/manual/en/function.file.php

person scrowler    schedule 30.01.2014
comment
Это работает для небольшого файла. Если у вас есть огромный CSV-файл (размером в ГБ), использование file() для чтения всего файла и count(), вероятно, является плохой идеей, поскольку он сохраняет файл в памяти и может привести к зависанию системы с низким объемом памяти. - person Tan Hong Tat; 30.01.2014
comment
@TanHongTat есть ли более эффективный способ сделать это? - person xd6_; 06.08.2014
comment
@xd6_ этот ответ будет более эффективным для больших файлов - person scrowler; 06.08.2014
comment
Просто имейте в виду, что нет простого способа сделать все это, который бы охватывал 100% случаев, просто, потому что значение столбца CSV может содержать символ новой строки. Это означает, что для получения истинного количества «записей» в файле вам действительно придется проанализировать файл. - person Alex Skrypnyk; 21.06.2017

Создайте новую ссылку на файл, используя SplFileObject:

$file = new SplFileObject('test.csv', 'r');

Попробуйте seek до самого высокого значения Int, которое может обработать PHP:

$file->seek(PHP_INT_MAX);

Тогда на самом деле он будет искать самую высокую строку в файле, это ваша последняя строка, а последняя строка + 1 равна вашему общему количеству строк:

echo $file->key() + 1;

Сложно, но это позволит вам не загружать содержимое файла в память, что очень удобно при работе с действительно большими файлами.

person Leo Cavalcante    schedule 28.03.2017
comment
Великолепно, отлично работает, это должен быть лучший ответ. - person JeopardyTempest; 11.05.2017
comment
Работает с PHP ›= 5.1 и эффективно использует память. Используйте $file->rewind(), чтобы вернуться к началу файла. - person Vlad Preda; 15.05.2017
comment
Лучший ответ здесь - person Pete - iCalculator; 25.06.2018
comment
единственная проблема, с которой я столкнулся с этим ответом, заключается в том, что в моем самом первом тесте в файле csv была пустая строка в конце .... что отбрасывало все. Есть ли обходной путь, подобный приведенному выше FILE_SKIP_EMPTY_LINES - person Bill Garrison; 19.03.2019
comment
@BillGarrison, попробуйте: $file->setFlags(SplFileObject::SKIP_EMPTY) - person Leo Cavalcante; 19.03.2019
comment
@LeoCavalcante В итоге мне пришлось использовать эту комбинацию флагов, чтобы заставить ее работать (в Windows) $file->setFlags(SplFileObject::READ_AHEAD | SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE); - person Bill Garrison; 20.03.2019
comment
Проблема аналогична предыдущему решению, которое загружает весь файл: вы будете считать только физические строки, а файл csv может легко содержать новые строки, которые являются частью содержимого; поэтому результат будет искажен. - person Steve Horvath; 04.12.2019

Пытаться

$c =0;
$fp = fopen("test.csv","r");
if($fp){
    while(!feof($fp)){
          $content = fgets($fp);
      if($content)    $c++;
    }
}
fclose($fp);
echo $c;
person Nouphal.M    schedule 30.01.2014

Я знаю, что это довольно старо, но на самом деле я столкнулся с тем же вопросом. В качестве решения я бы предположил использовать специфичную для Linux логику:

$rows = shell_exec('$(/bin/which cat) file.csv | $(/bin/which tr) "\r" "\n" | $(which wc) -l');

ПРИМЕЧАНИЕ: это работает только для Linux и должно использоваться только в том случае, если вы на 100% уверены, что в вашем файле нет многострочных ячеек

person boesing    schedule 25.03.2015

Строки CSV разделяются разрывами строк. Поэтому разбивайте строки по переносам строк, и вы получите счетный массив строк.

if (($fp = fopen("test.csv", "r")) !== FALSE) { 
    $rows = explode("\n", $fp);
    $length = count($rows);

    echo $length;
}
person Community    schedule 30.01.2014
comment
На самом деле вы не читаете из указателя файла. И если вы просто считаете строки, то count(file("test.csv")) сделает это быстрее. Однако в некоторых вариантах CSV значения в кавычках могут содержать разрывы строк. - person mario; 30.01.2014

Примечание; ни одно из решений с более высоким рейтингом, которые подсчитывают строки в файле, не являются надежными, поскольку они подсчитывают только строки, а не записи csv (которые могут содержать символы новой строки)

Я использую аналогичное решение для op, и оно работает отлично, но с кодом op часть while может прерываться на пустых строках, что потенциально является его проблемой.

Так это выглядит так (отредактированный код операции)

$rowCount=0;
if (($fp = fopen("test.csv", "r")) !== FALSE) {
  while(!feof($fp)) {
    $data = fgetcsv($fp , 0 , ',' , '"', '"' );
    if(empty($data)) continue; //empty row
    $rowCount++;
  }
  fclose($fp);
}
echo $rowCount;
person Steve Horvath    schedule 04.12.2019
comment
Разве это не то же самое, что и этот ответ двухлетней давности? - person scrowler; 04.12.2019
comment
Спасибо, @Robbie Averill, если честно, я не уверен, что это приведет к одному и тому же результату во всех обстоятельствах - особенно к пустым строкам. У меня такое чувство, что в другом ответе просто будут считаться пустые строки, а в этом определенно нет. Мне стыдно за то, что я пропустил обзор ответов с отрицательным рейтингом, это действительно достаточно близко. - person Steve Horvath; 05.12.2019

Я считаю это самым надежным:

$file = new SplFileObject('file.csv', 'r');
$file->setFlags(
    SplFileObject::READ_CSV |
    SplFileObject::READ_AHEAD |
    SplFileObject::SKIP_EMPTY |
    SplFileObject::DROP_NEW_LINE
);

$file->seek(PHP_INT_MAX);

$lineCount = $file->key() + 1;
person Jonathan    schedule 17.12.2020
comment
Я бы, наверное, проголосовал за это, если бы было объяснение. У меня есть политика против голосования за дампы фрагментов, даже если они полезны/хороши. - person mickmackusa; 17.12.2020

Я знаю, что это старый пост, но я погуглил эту проблему и обнаружил, что единственная проблема с исходным кодом заключалась в том, что вам нужно определить $row вне цикла while, например:

if (($fp = fopen("test.csv", "r")) !== FALSE) { 
$row = 1;
  while (($record = fgetcsv($fp)) !== FALSE) {
      $row++;
  }

На всякий случай это кому-то поможет :) echo $row; }

person Rosamunda    schedule 16.03.2017

Если вы получаете файл из формы

$file = $_FILES['csv']['tmp_name'];
                $fp = new SplFileObject($file, 'r');
                $fp->seek(PHP_INT_MAX);
                echo $fp->key() + 1;
                $fp->rewind();

Работает как шарм!!!!!!!!!!!!!!!!!!!

person kimoduor    schedule 07.06.2017

person    schedule
comment
Добавьте некоторое объяснение с ответом о том, как этот ответ помогает ОП в устранении текущей проблемы. - person ρяσѕρєя K; 04.07.2017