2016-09-04 22 views
0

データベースにインポートする必要のあるサービスを経由してくるCSVファイルを格納できるディレクトリがあります。これらのCSVファイルはそれぞれ1000行で、10〜150ファイルにすることができます。PHPを別のプロセスで長時間実行する

これらのすべてのCSVファイルのデータをデータベースに挿入します。問題は、私がset_time_limit(0)を使用しても、サーバ(siteground.com)がその制限を課すため、タイムアウトの問題でPHPが動作しなくなることです。

// just in case even though console script should not have problem 
ini_set('memory_limit', '-1'); 
ini_set('max_input_time', '-1'); 
ini_set('max_execution_time', '0'); 
set_time_limit(0); 
ignore_user_abort(1); 
/////////////////////////////////////////////////////////////////// 

function getRow() 
{ 
    $files = glob('someFolder/*.csv'); 

    foreach ($files as $csvFile) { 
     $fh = fopen($csvFile, 'r'); 

     $count = 0; 
     while ($row = fgetcsv($fh)) { 
      $count++; 

      // skip header 
      if ($count === 1) { 
       continue; 
      } 

      // make sure count of header and actual row is same 
      if (count($this->headerRow) !== count($row)) { 
       continue; 
      } 

      $rowWithHeader = array_combine($this->headerRow, $row); 

      yield $rowWithHeader; 
     } 
    } 
} 

foreach(getRow() as $row) { 
    // fix row 
    // now insert in database 
} 

これはコマンドartisanを介して実行実際には(私はLaravelを使用しています):ここではコードです。 CLIには時間制限がないことがわかっていますが、何らかの理由ですべてのCSVファイルがインポートされず、特定の時点でプロセスが終了するわけではありません。

私の質問は、ディレクトリにあるCSVファイルごとに別々のPHPプロセスを呼び出す方法ですか?またはこれを行う他の方法は、PHPのgenerator,などのような問題なしですべてのCSVファイルをインポートすることができる

+1

に各.csvファイルのスクリプトを実行します時間を過ごすことができます。 CLIを介してPHPを実行するだけでも役に立ちません。彼はただそのプロセスを殺すことができます。 –

+0

リモートデータベースに接続しているときにlocalhostからPHPスクリプトを実行してみませんか?ローカルでは、スクリプトの時間制限を設定することはできません。 –

+0

@RobertTrzebiński:それは実際にサーバー上で実行する必要があります。 – dev02

答えて

0

最高のアプローチは、1つのPHPプロセスあたりの限られた数のファイルを処理することです。たとえば、10(経験的な数のファイルを計算する)で始まり、処理し、削除済みとしてマークし(処理されたファイルを含むフォルダに移動)、プロセスを停止することができます。その後、別の10個のファイルをインポートする新しいプロセスを開始します。 Laravelでは、別のプロセスが既に動作している場合、特定のコマンドに対して複数のプロセスを開始しないと言うことができます。 Laravelのためのコマンドは以下の通りです:

$schedule->command("your job")->everyMinute()->withoutOverlapping(); 

あなたがこのアプローチを使用している場合は、すべてのファイルが特定の時間のために処理されますと、彼らは殺されるためにあまりにも多くのリソースを消費しないことを確認することができます。

0

ホスティングプロバイダがcronジョブを許可している場合、タイムアウトの制限はありません。

また、重いと長いタスクの関数を手動で呼び出すよりも仕事に合っている必要があります。

1

あなたはちょうどbashの魔法をやることができます。 1つのファイルだけを処理するようにスクリプトをリファクタリングします。処理するファイルはスクリプトの引数で、$argvを使用してアクセスします。

<?php 
// just in case even though console script should not have problem 
ini_set('memory_limit', '-1'); 
ini_set('max_input_time', '-1'); 
ini_set('max_execution_time', '0'); 
set_time_limit(0); 
ignore_user_abort(1); 
$file = $argv[1]; // file is the first and only argument to the script 
/////////////////////////////////////////////////////////////////// 

function getRow($csvFile) 
{ 
    $fh = fopen($csvFile, 'r'); 

    $count = 0; 
    while ($row = fgetcsv($fh)) { 
     $count++; 

     // skip header 
     if ($count === 1) { 
      continue; 
     } 

     // make sure count of header and actual row is same 
     if (count($this->headerRow) !== count($row)) { 
      continue; 
     } 

     $rowWithHeader = array_combine($this->headerRow, $row); 

     yield $rowWithHeader; 
    } 
} 

foreach(getRow($file) as $row) { 
    // fix row 
    // now insert in database 
} 

さて、このようなあなたのスクリプトを呼び出す:ホスティングプロバイダは、スクリプトが限られたために実行されることを望んでいる場合

for file in `ls /path/to/folder | grep csv`; do php /path/to/your/script.php /path/to/folder/$file; done 

これはあなたの/path/to/folder

関連する問題