2010-11-18 10 views
2

タブ区切りのファイルを含むフォルダを1つずつ順番に解析し、データをmysqlデータベースに挿入するPHPスクリプトがあります。私はサーバーのセキュリティ上の制限のためにLOAD TABLEを使用することができず、設定ファイルにアクセスすることはできません。このスクリプトは、1つまたは2つの小さいファイルを解析するだけで動作しますが、いくつかの大きなファイルを扱うときには500のエラーが発生します。エラーに関連するメッセージを含むエラーログは表示されません。少なくとも、ホスティングプロバイダが私にアクセス権を与えるものはありません。以下はコードですが、私はまた、私がしなければならないことをやり遂げる代わりの方法の提案もしています。最終的には、このスクリプトを30分ごとに起動し、新しいデータを挿入して終了したらファイルを削除します。PHPで多くのmysql_queryを呼び出した後に500エラーが発生しました

EDIT:Philが変更を提案した後でもスクリプトは失敗しますが、私のエラーログに次のメッセージが表示されます: "mod_fcgid:120秒でデータのタイムアウトを読み込み"、スクリプトがタイムアウトしたようですタイムアウトの設定を変更できますか?

$folder = opendir($dir); 
    while (($file = readdir($folder)) !== false) { 
     $filepath = $dir . "/" . $file; 

     //If it is a file and ends in txt, parse it and insert the records into the db 
     if (is_file($filepath) && substr($filepath, strlen($filepath) - 3) == "txt") { 
      uploadDataToDB($filepath, $connection); 
     } 
    } 

function uploadDataToDB($filepath, $connection) { 
    ini_set('display_errors', 'On'); 
    error_reporting(E_ALL); 
    ini_set('max_execution_time', 300); 

    $insertString = "INSERT INTO dirty_products values("; 

    $count = 1; 

    $file = @fopen($filepath, "r"); 

    while (($line = fgets($file)) !== false) { 
     $values = ""; 
     $valueArray = explode("\t", $line); 
     foreach ($valueArray as $value) { 
      //Escape single quotes 
      $value = str_replace("'", "\'", $value); 
      if ($values != "") 
       $values = $values . ",'" . $value . "'"; 
      else 
       $values = "'" . $value . "'"; 
     } 

     mysql_query($insertString . $values . ")", $connection); 
     $count++; 
    } 

    fclose($file); 

    echo "Count: " . $count . "</p>"; 
} 

答えて

1

まず、準備されたステートメント(PDOを使用)を使用します。

mysql_query()機能を使用すると、挿入ごとに新しいステートメントが作成され、許容範囲を超えている可能性があります。

プリペアドステートメントを使用すると、1つのステートメントだけが作成され、データベースサーバーでコンパイルされます。

function uploadDataToDB($filepath, $connection) { 
    ini_set('display_errors', 'On'); 
    error_reporting(E_ALL); 
    ini_set('max_execution_time', 300); 

    $db = new PDO(/* DB connection parameters */); 
    $stmt = $db->prepare('INSERT INTO dirty_products VALUES (
         ?, ?, ?, ?, ?, ?)'); 
    // match number of placeholders to number of TSV fields 

    $count = 1; 

    $file = @fopen($filepath, "r"); 

    while (($line = fgets($file)) !== false) { 
     $valueArray = explode("\t", $line); 
     $stmt->execute($valueArray); 
     $count++; 
    } 

    fclose($file); 
    $db = null; 

    echo "Count: " . $count . "</p>"; 
} 

スケジュール上でこのスクリプトを実行したい考えると、私は、Webサーバーを完全に回避し、あなたのホストが提供するcronか何かスケジューリングサービス使用してCLI経由でスクリプトを実行すると思います。これにより、Webサーバーで設定されたタイムアウトを回避できます。

+0

今は失敗する前にもっと多くの行を処理しているようですが、最終的にはすべてのファイルを解析する前に500のエラーが表示されます。つまり、私のエラーログには便利なメッセージが含まれています。 "mod_fcgid:120秒でデータのタイムアウトを読み込む"すばらしいgoogle検索では解決策が見つかりませんでしたが、私は探し続けます。 –

+0

おそらくApacheのCGIスクリプトのタイムアウトのようです。このスクリプトをスケジュールどおりに実行したいと考えるなら、Webサーバーを完全に避けて、CLIを使用してスクリプトを実行するか、ホストが提供するスケジューリングサービスをcronで実行します。 – Phil

+0

ええ、あなたが正しいと思います。ありがとう。あなたが答えとしてそれを置くなら、私はそれを受け入れます。 –

関連する問題