-1

I have a csv which includes a column allowing a multi-line string.

sku,name,description
123,"Product Name Here","Multi-line description
goes here.
Lots of multi-line content"

I am interested in counting the number of rows I have in my CSV. I have tried

 $num_rows = count(file($filename));
 var_dump($num_rows); //4 < WHAY too high

but this counts each line in the multi-line cell as well.

To get the actual number of lines I am currently using:

//get number of rows
$num_rows = 0;
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
    $num_rows++;
}
var_dump($num_rows); //2 < The actual number of rows

I then do another while loop to process the CSV.

Is there a way to get the number of rows in a CSV without using the above while loop?

CSV

Here is a sample CSV. The number of lines I am looking for is 3 not 28

sku, name, description
123, "Product name", "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>

<p>Mauris pretium enim facilisis, tincidunt elit id, congue est.</p>

<p>Donec eu eros quis elit mattis dapibus.</p>

<p>Sed euismod augue nec metus accumsan, et ultricies elit mattis.</p>

<p>Vestibulum aliquet est sit amet neque congue lacinia.<br/>
Donec viverra augue quis orci interdum mattis.<br/>
Phasellus ullamcorper risus quis dolor tempus sagittis.</p>

<p>Integer vel augue iaculis turpis vestibulum commodo eu quis nunc.</p>"

456, "Another Product name", "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>

<p>Mauris pretium enim facilisis, tincidunt elit id, congue est.</p>

<p>Donec eu eros quis elit mattis dapibus.</p>

<p>Sed euismod augue nec metus accumsan, et ultricies elit mattis.</p>

<p>Vestibulum aliquet est sit amet neque congue lacinia.<br/>
Donec viverra augue quis orci interdum mattis.<br/>
Phasellus ullamcorper risus quis dolor tempus sagittis.</p>

<p>Integer vel augue iaculis turpis vestibulum commodo eu quis nunc.</p>"
Community
  • 1
  • 1
Richard Parnaby-King
  • 14,703
  • 11
  • 69
  • 129
  • 1
    `$rows = count(explode("\r\n", file_get_contents('myCSVfile.csv')));` ? – hresult Jun 29 '15 at 11:10
  • 1
    @sandnig hope the newline will ever be \r\n ,) – donald123 Jun 29 '15 at 11:10
  • 3
    No, there isn't any shortcut method, your while loop is the only method that will return a correct result – Mark Baker Jun 29 '15 at 11:13
  • 1
    @sandnig And won't this have the same issue, counting linebreaks _inside_ cells which should not be counted? – arkascha Jun 29 '15 at 11:13
  • @arkascha you are right, my fault – hresult Jun 29 '15 at 11:15
  • 1
    I think the `fgetcsv()` approach is the way to go, since you simply do need knowledge about the csv format whilst parsing here. All other approaches will be much more complex, since you have to implement that knowledge. – arkascha Jun 29 '15 at 11:16
  • @sandnig Nope, the multi-line column gets exploded as well and inflates the row count. – Richard Parnaby-King Jun 29 '15 at 11:23
  • Since your row always starts with a number (id), why not use RegEx? Don't kill me for this, but here it goes: `preg_match_all('#\d+,#', $csv, $rows);` `$rows = count($rows[0]) +1;` - returns 3 on your example – hresult Jun 29 '15 at 12:00

2 Answers2

0

In PHP5 you have a very fast solution for small-medium sized files:

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

source: How can I get the total number of rows in a CSV file with PHP?

If file is huge, better use this scheme, like is said in post:

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

If you only want to count carriage returns (line breaks) try this:

$count = substr_count(file_get_contents($filename), "\r\n");

source: Count New Lines in Text File

Community
  • 1
  • 1
manuelbcd
  • 3,106
  • 1
  • 26
  • 39
0

If your description entries are always enclosed in quotes:

$matches = array();
preg_match_all("/(description|\")$/m", file_get_contents($filename), $matches);  

now sizeof($matches[1]) contains number of rows in CSV

Tom Pimienta
  • 109
  • 3