3

50 メガバイトの .csv ファイルを解析しようとしています。ファイル自体は問題ありませんが、関連する大規模なタイムアウトの問題を回避しようとしています。ファイルを簡単にアップロードして再度開くことができますが、ブラウザのタイムアウト後に 500 内部エラーが発生します。

ファイルをサーバーに保存して開き、処理した行のセッション値を保持できると思います。特定の行の後、更新を介して接続をリセットし、中断した行でファイルを開きます。これは実行可能なアイデアですか?前の開発者は非常に非効率な MySQL クラスを作成し、それがサイト全体を制御しているため、必要がなければ独自のクラスを作成したくありません。また、彼のクラスを台無しにしたくありません。

TL;DR バージョン: 38,000 行の製品がある CSV ファイルの現在の最後の行を保存し、X 行の後に接続をリセットして、中断したところから開始するのは効率的ですか? または、タイムアウトなしで大きな CSV ファイルを解析する別の方法はありますか?

注: PHP スクリプトの実行時間です。現在 38,000 行で、コマンド ラインからの実行には約 46 分 5 秒かかります。ブラウザーから削除すると、100% 正しく動作し、ブラウザーのタイムアウトであることを示唆しています。Google が私に言った限り、Chrome のタイムアウトは編集できず、Firefox のタイムアウトはめったに機能しません。

4

3 に答える 3

3

次のようなことができます。

<?php

namespace database;

class importcsv
{
    private $crud;

    public function __construct($dbh, $table)
    {
        $this->crud = new \database\crud($dbh, $table);
        return $this;
    }

    public function import($columnNames, $csv, $seperator)
    {
        $lines = explode("\n", $csv);

        foreach($lines as $line)
        {
            \set_time_limit(30);
            $line = explode($seperator, $line);

            $data = new \stdClass();

            foreach($line as $i => $item) 
            {
                if(isset($columnNames[$i])&&!empty($columnNames[$i]))
                    $data->$columnNames[$i] = $item;
            }

            @$x++;

            $this->crud->create($data);
        }

        return $x;
    }

    public function importFile($columnNames, $csvPath, $seperator)
    {
        if(file_exists($csvPath))
        {
            $content = file_get_contents($csvPath);
            return $this->import($columnNames, $content, $seperator);
        }
        else
        {
            // Error
        }
    }
}

TL;DR:\set_time_limit(30);行をループするたびに、タイムアウトの問題が解決する場合があります。

于 2012-08-03T17:07:08.923 に答える
2

コマンドラインからphpを実行し、cronジョブとして設定することをお勧めします。この方法では、コードを変更する必要はありません。タイムアウトの問題はなく、大きな CSV ファイルを簡単に解析できます。

このリンクもチェックしてください

于 2012-08-03T17:19:22.760 に答える
1

あなたの投稿は、タイプミスと文法のために少し不明瞭です。編集していただけますか?

アップロード自体は問題ないが、遅延がファイルの処理にあると言う場合、最も簡単な方法は、複数のスレッドを使用してファイルを並行して解析することです。これを行うには、Java 組み込みの Executor クラス、または Quartz または Jetlang を使用できます。

  • ファイルのサイズまたは行数を見つけます。
  • スレッド負荷を選択します (スレッドごとに 1000 行とします)
  • エグゼキュータを開始する
  • ファイルをループで読み取ります。
  • 1000 行ごとに Runnable を作成し、Executor にロードします。
  • エグゼキュータを起動する
  • すべてのスレッドが終了するまで待ちます

各ランナブルはこれを行います:

  1. 接続をフェッチする
  2. 1000行挿入
  3. 結果をログに記録する
  4. 接続を閉じる
于 2012-08-03T17:06:33.553 に答える