0

テキスト ファイル (実際には imdb の「リスト」ファイル) を実行し、それをローカルの MySQL データベースに保存する PHP スクリプトを作成しました。

public static function updateMovies( $list ) {
    $offset = 15;               // movies.list start with movie names at line 16
    $handle = fopen($list, "r") or die("Couldn't get handle");
    if ($handle) {
        while (!feof($handle)) {
            $buffer = fgets($handle);
            if($offset!=0)
                $offset--;
            else
                if($buffer[0] != '"'){
                    $title = trim( substr( $buffer, 0, strpos( $buffer, '(' ) ) );
                    $year = intval(trim( substr( $buffer, strpos( $buffer,'(' )+1, 4 ) ));
                    Movie::create( $title, $year );
                }
        }
        fclose($handle);
    }
}

これらのリスト ファイルは最大 200 MB になるため、かなりの時間がかかります。デフォルトでは、PHPMAX_EXECUTION_TIMEは 30 秒に設定されています。

この値を 300 に設定して、機能するかどうかを試してみました。たとえば、私の「movies.list」ファイルは約 80MB で、このスクリプトを 300 秒間使用すると、データベースに約 25000 行が作成されます。「B」で始まる映画にさえ到達していないため、これは機能しません。

を 0 (無制限) に設定できることはわかっていますMAX_EXECUTION_TIMEが、将来、このデータベースを自分のローカルホストに配置したくありません。MAX_EXECUTION_TIME私は自分のウェブサーバーにそれを置きたいのですが、私の知る限り、私のウェブサーバーのホストは 90 に設定されています。

これをどのように処理するかについてのアイデアはありますか?

4

2 に答える 2

1

set_time_limit(sec)を使用するか、(より良い)コマンドラインから cron エントリを介して スクリプトを実行します。そうすれば、PHP に関連しない他の多くのタイムアウトの問題を回避できます。

于 2012-04-22T17:18:28.770 に答える
1

この種の大きなファイルをデータベースに直接ロードするのは良い考えではないと思います...特に結論に非常に長い時間がかかる場合

私のアドバイス

ファイルをローカルで小さなチャンクに分割し、リモートサーバーでデータベースにアップロードします

例 (ドキュメント: http://en.wikipedia.org/wiki/Split_%28Unix%29 )

 exec('split -d -b 2048m ' . $list . ' chunks');

純粋な PHP の実装については、以下を参照してください。

http://www.php.happycodings.com/File_Manipulation/code50.html

または

define('CHUNK_SIZE', 1024*1024);
function readfile_chunked($filename, $retbytes = TRUE) {
    $buffer = '';
    $cnt =0;
    // $handle = fopen($filename, 'rb');
    $handle = fopen($filename, 'rb');
    if ($handle === false) {
      return false;
    }
    while (!feof($handle)) {
      $buffer = fread($handle, CHUNK_SIZE);
      echo $buffer;
      ob_flush();
      flush();
      if ($retbytes) {
        $cnt += strlen($buffer);
      }
    }
    $status = fclose($handle);
    if ($retbytes && $status) {
      return $cnt; // return num. bytes delivered like readfile() does.
    }
    return $status;
  }
于 2012-04-22T19:53:08.627 に答える