1

PHP関数定義ページfilegetcsvを含む、インターネット全体で見つかった次のコードを使用して、CSVファイルを解析し、それを処理しようとしています:

if (($handle = fopen("test.csv", "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
        print_r($data);
    }
    fclose($handle);
}

$data =しかし、このコードでは、次の行で警告の無限ループが発生します。

PHP Warning: fgetcsv() expects parameter 1 to be resource, boolean given in...
  1. ファイル名にダミー文字を追加すると、別のエラーが発生し、ループが発生しないため、開いているファイルが有効なファイルであることはわかっています。
  2. ファイルは、完全なアクセス許可を持つフォルダーにあります。
  3. Mac 上の Excel で生成された CSV を使用していません (風変わりなエラーがあります) 。
  4. PHPのバージョンは5.1.6なので機能的には問題ないはずです
  5. ファイルが大きすぎたり、形式が正しくないことはわかっています。元のファイルを縮小し続けて問題があるかどうかを確認し、最終的にメモ帳で次のような 2 行しかないカスタム ファイルを作成したからです。

    値 1A、値 1B、値 1C、値 1D

まだループしており、データがありません。これが私が現在取り組んでいる完全なコードです(実際にサーバーに無限ループを与えずに無限ループすることを証明できるように、行数よりも大きい変数を使用しています)

if ($handle = fopen($_SERVER['DOCUMENT_ROOT'].'/tmp/test-csv-file.csv', 'r') !== FALSE) {
    while ((($data = fgetcsv($handle, 1000, ',')) !== FALSE) && ($row < 10)) {
        print_r($data);
        $row++;
    }
    fclose($handle);
}

だから私は本当に2つの質問があります。

1) このループの原因となっているのは、何を見落としている可能性がありますか? 私はそれが本当に「顔と手のひら」のような単純なものだと半分確信しています...

2) この関数の推奨コードが、ファイルが存在するが未知の問題がある場合に無限ループを引き起こす可能性があるのはなぜですか? !== FALSEなどの目的は、そのようなことを防ぐことだと思っていたでしょう。

4

2 に答える 2

6

ここで何が起こっているのか疑問の余地はありません: ファイルが正常に開かれていません。そのため、 はリソースで$handleはなく (自分で確認するため) です。boolvar_dump($handle)

fgetcsvその後、エラーが発生したためnull(not !)を返します。ドキュメントに記載されているように:false!== false

fgetcsv() は、無効なハンドルが指定された場合は NULL を返し、ファイルの終わりを含むその他のエラーの場合は FALSE を返します。

null異なるエラー条件に対してandを返すことfalseは理想的ではないことに同意します。さらに、他の多くの関数によって確立された先例に反することにも同意しますが、それはまさにその通りです (そして事態はさらに悪化する可能性があります )。現状では、テストを次のように変更するだけです。

while ($data = fgetcsv($handle, 1000, ","))

どちらの場合でも正しく機能します。

アップデート:

あなたは条件内の代入の犠牲者ですif:

if ($handle = fopen($_SERVER['DOCUMENT_ROOT'].'/tmp/test-csv-file.csv', 'r') !== FALSE)

になるはずだった

// wrap the assignment to $handle inside parens!
if (($handle = fopen($_SERVER['DOCUMENT_ROOT'].'/tmp/test-csv-file.csv', 'r')) !== FALSE)

ここで何がうまくいかなかったのか、あなたは理解していると確信しています。これが、条件内で代入を絶対に行わないことを選択した理由です。それが可能であることは気にしません。短くても構いません。割り当てが削除された場合、ループを記述するのが「エレガント」ではない場合があることさえ気にしません。自分の正気を大切にするなら、同じことを考えてみてください。

于 2011-12-07T17:26:21.683 に答える
0
            $row = 1;
            if (($handle = fopen($_FILES['csv-file']['tmp_name'], "r")) !== FALSE) {
                $data = fgetcsv($handle , 1000 , ",");
                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);
            }

与えられたコード スニペットを一度試してみてください。なぜなら、コードにいくつかの重要なものが欠けていることに気付いたからです。

于 2018-09-29T16:19:36.213 に答える