2017-04-25 24 views
0

パラメータから.csvファイルとこの配列のmyrownumber(.csvの行を示す数字)を取得する関数があります。PHPでcsvファイルの特定の行を読む

これは、csvファイルの行番号myrownumberの内容を返します。

private function readASpecificRow($filePath, $myrownumber) 
{ 
    $rowImLookingFor = array(); 
    $f = fopen($filePath, "r"); 
    $i = 0; 
    while (($line = fgetcsv($f)) !== false) 
    { 
     $i ++; 
     foreach ($line as $cell) 
     { 
      if ($i == $myrownumber) 
      { 
       array_push($rowImLookingFor, $cell); 
      } 
     } 
    } 
    fclose($f); 

    return($rowImLookingFor); 
} 

これは、私が探している行が見つかるまで、すべてのファイルを繰り返し処理するので非常に非効率的です。

csvファイルの行番号myrownumberを直接読み取る方法はありますか?

PS:多くの解決策がありますが、fgetcsvを使用してください。セルには改行がいくつかあり、fgetscsvで制御しています。私がfileなどを使用している場合、いくつかのセルの内部で改行が行われるため、行の数はcsvの実数とは異なります。

ありがとうございます。

+1

あなたは 'foreach'の外で' $ i == $ myrownumber'を取るこ​​とができます。各行でのみ変更されるときに、各セルごとにチェックする必要はありません。 – Ezenhis

答えて

0

file()を使用して、ファイルを行単位で取得することができます。具体的には、str_getcsvを使用して特定の行をCSVに解析します。

+0

投稿を読んでください、私は 'fgetscsv'を使い続けたいと思います。 'file()'を使うと、行数は元の 'csv'ファイルと異なっています。セルに改行があるからです。 –

+0

@Aviónこれらの新しいラインは後で必要ですか? – Justinas

+0

あなたはどういう意味ですか? –

0

私はこれがあなたに別の解決策を提供していないことを知っていますが、想定された非効率性を助けることができます。

私は個人的にはもっとこのように見えるように機能をリファクタリングしたい:

private function readASpecificRow($filePath, $myrownumber) 
{ 
    $f = fopen($filePath, "r"); 
    $i = 0; 
    $myrownumber = (int) $myrownumber; // ensure it's actually a number. 
    while (($line = fgetcsv($f)) !== false) 
    { 
     if (++$i < $myrownumber) continue; 
     fclose($f); 
     return $line; 
    } 
    return false; // if the specified line wasn't there return false 
} 

それは少し速くする必要があります。

0

単純な直接行読み込みを開始するための方法が、何あなたがこの方法を試すことができますありません:

$pre_pos = <previous position>; 
fseek($file, $pre_pos); 
while(...) { 
    fgetcsv(...); 
    ... 
} 
$pre_pos = ftell($file); 
0

あなたはファイル全体を反復処理する必要がありますが、あなたの行を作るために発見された後、あなたが早期に返すことができますが、それはもう少し効率的です。

private function readASpecificRow($filePath, $myrownumber) 
{ 
    $f = fopen($filePath, "r"); 

    for($i = 1; $line = fgetcsv($f); $i++) { 
     if($i === $myrownumber) { 
      fclose($f); 
      return $line; 
     } 
    } 

    return false; 
} 

注意を$myrownumberが1であれば、それは最初の行を返しますので、これは、ゼロベースではないこと:それは除去することができるので、私は、各ラインの内側のforeachループの必要性を見ることができません。 forループの$i = 1;$i = 0に変更してゼロベースにします。

関連する問題