web-dev-qa-db-ja.com

すべての行を返すphp fgetcsv

次のcsvファイルがあります。

_upc/ean/isbn,item name,category,supplier id,cost price,unit price,tax 1 name,tax 1 percent,tax 2 name,tax 2 percent,quantity,reorder level,description,allow alt. description,item has serial number
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
,Apple iMac,Computers,,10,12,8,8,10,10,10,1,Best computer,,
_

私がこれをするとき:

_if (($handle = fopen($_FILES['file_path']['tmp_name'], "r")) !== FALSE) 
{
    $data = fgetcsv($handle);
    var_dump($data);
}
_

183要素の配列を取得します。csvの1行しか取得しないと思いますが、ファイル全体を取得します。

私も$data = fgetcsv($handle, 1000);を試しましたが、同じ結果が得られました

37
Chris Muench

これはおそらく行末の問題です。有効にしてみてください auto_detect_line_endings ファイルの行末を判別しようとします。

ini_set('auto_detect_line_endings', true);

それでも問題が解決しない場合は、detectfile コマンドを使用してラインターミネータのタイプを検出します:

$ file example.csv
example.csv: ASCII text, with CR line terminators

次に、行末をconvertできます。使用しているOSはわかりませんが、 ファイル形式の変換に役立つユーティリティ がたくさんあります。 dos2unix

102
mholzmann

これは私が考えることができる最も短い解決策です:

$fp = fopen('test.csv', 'r');

// get the first (header) line
$header = fgetcsv($fp);

// get the rest of the rows
$data = array();
while ($row = fgetcsv($fp)) {
  $arr = array();
  foreach ($header as $i => $col)
    $arr[$col] = $row[$i];
  $data[] = $arr;
}

print_r($data);

出力:

Array
(
    [0] => Array
        (
            [upc/ean/isbn] => 
            [item name] => Apple iMac
            [category] => Computers
            [supplier id] => 
            [cost price] => 10
            [unit price] => 12
            [tax 1 name] => 8
            [tax 1 percent] => 8
            [tax 2 name] => 10
            [tax 2 percent] => 10
            [quantity] => 10
            [reorder level] => 1
            [description] => Best computer
            [allow alt. description] => 
            [item has serial number] => 
        )

    [1] => Array
        (
            [upc/ean/isbn] => 
            [item name] => Apple iMac
            [category] => Computers
            [supplier id] => 
            [cost price] => 10
            [unit price] => 12
            [tax 1 name] => 8
            [tax 1 percent] => 8
            [tax 2 name] => 10
            [tax 2 percent] => 10
            [quantity] => 10
            [reorder level] => 1
            [description] => Best computer
            [allow alt. description] => 
            [item has serial number] => 
        )

    // ...

    [11] => Array
        (
            [upc/ean/isbn] => 
            [item name] => Apple iMac
            [category] => Computers
            [supplier id] => 
            [cost price] => 10
            [unit price] => 12
            [tax 1 name] => 8
            [tax 1 percent] => 8
            [tax 2 name] => 10
            [tax 2 percent] => 10
            [quantity] => 10
            [reorder level] => 1
            [description] => Best computer
            [allow alt. description] => 
            [item has serial number] => 
        )

)
6
Czechnology

試してください:

_ while (($data = fgetcsv($handle, 0, ',')) !== FALSE) {
    $columns = count($data);
 }
_

または、str_getcsv(file_get_contents(...))を使用してみることもできます

1
Martin

Macでは、Microsoft Excelで生成されたCSVファイルで同じ問題が発生しました。別のファイルに対してコマンドmoreを実行したところ、行末が異なっているようです。

$ more Excel.csv && more test.csv
[email protected]^[email protected]^[email protected]^M
[email protected]
[email protected]
[email protected]

使った

ini_set('auto_detect_line_endings', true);

fgetcsv($handle, 0, ';')

そしてそれは動作します。受け入れられた答えは正しいです。

1

CSVファイル全体を一度に読み取るには、次のコマンドを使用します。

$data = array_map("str_getcsv", file($fn));
var_dump($data);

ただし、最初の行はarray_shift()する必要があります(列キーを使用しない場合)。


不特定の行末の回避策:

$data = array_map("str_getcsv", preg_split('/[\r\n]+/', file_get_contents($fn)));
var_dump($data);
1
mario

オプションがある場合は、.csvファイルを編集して「Unix」スタイルの行末を含めるように編集します。その後、fgetcsvは自動的に配列を行末で分割します

0
Dr Nick Engerer