2016-12-14 14 views
1

ファイルからデータを取得してグラフ化するPHP Webプログラムを作成しています。サーバー上のコマンドラインで実行するとうまくいきますが、比較的少量のデータに対してブラウザからは動作しますが、ファイルが1.2または130万行(30文字/行、3.5または4MB )、私はHTTPエラー500を取得します。奇妙なことは、矛盾した動作です。 125万回線で、時にはうまく動作しないことがあります。 apacheのための1とCLIで異なる1 - PHPは、2つの異なるphp.iniのファイルを持っている、いくつかのシステムでは大量のデータでPHPプログラムが失敗する

<?php 

$wait = $_GET["wait"]; 
$measure = $_GET["measure"]; 
$graphsize = $_GET["graphsize"]; 
$title = "Current"; 
if ($measure == "CURR") $title = "Current (A)"; 
if ($measure == "VOLT") $title = "Voltage (V)"; 
if ($measure == "RES") $title = "Resistance (Ohms)"; 

$page = $_SERVER["PHP_SELF"]; 

$data = array(array("Time", $title)); 
$datasize = filesize("data.csv")/30; 
$x = 0; 

$file = fopen("data.csv", "r"); 
while (($datum = fgets($file)) !== False) { 
    $x++; 
    if ($x % ($datasize/$graphsize) == 0) { 
     $datum = explode(",", $datum); 
     $datum[0] = floatval($datum[0]); 
     $datum[1] = floatval($datum[1]); 
     $data[] = $datum; 
    } 
} 
fclose($file); 

if (count($data) == 1) $data[] = array(0,0); 

?> 

graphing stuff down here, I'm pretty sure this isn't the problem 
+0

あなたはhughアレイを構築しています。エラーログにはどのようなエラーが表示されますか? – RiggsFolly

+0

いくつかのエラー報告を追加して、エラーを表示しないように設定されたサーバで実行している場合に実際にエラーを表示する 'ini_set( 'display_errors'、1); ini_set( 'log_errors'、1); error_reporting(E_ALL); ' – RiggsFolly

答えて

1

: は、ここでは、コードです。通常、CLIのiniファイルはmax_execution_timeに制限を設けず、memory_limitの値も大きくなっています。これはおそらく、CLIを介して実行されているがWebサーバー経由では実行されていない理由を説明します。

ファイルを1行ずつ解析するのは、ファイル全体の内容を一度に読み取るよりも少ないメモリを消費するため、1行ずつ解析することをお勧めします。あなたは、実際にファイルを開いていることを確認するためのfopenの結果を確認する必要があります

$file = fopen("data.csv", "r"); 
if (!$file) { 
    throw new Exception("Could not open data file"); 
} 

Webサーバを介してアクセスするとき、あなたのスクリプトが5XX結果を返している場合、これは通常、PHPスクリプトが致命的なエラーが発生しました調子。私は、あなたがどちらかというと、a)時間がなくなっているか、b)記憶がなくなっていることを推測しています。調べるには、PHPエラーを調べる必要があります。ブラウザに直接出力されていない場合は、PHPのログがどこにあるかを調べる必要があります。これに指定された値が存在する場合もあれば、存在しない場合もあります。値が設定されているかどうかを確認するために、これを試してみてください:

echo ini_get("error_log"); 

をこの値が空の場合、このディレクティブが設定されていない

場合は、エラーはSAPIエラーロガーに送信されます。たとえば、CLIのApacheまたはstderrのエラーログです。私のUbuntuマシンで

、このファイルはそのように各ドメインのApacheのconfファイルに設定されています。

ErrorLog /var/www/site_name/log/error.log 

しかし、それはあなたのマシン上では全く違うものになるかもしれません。見つけられない場合は、set_error_handler関数を使用して、エラーを横取りしてファイルに書き込んだり電子メールで送信したり、ちょうど吐き出したりすることができます。

あなたのphp.iniの設定のカップルのために設定した制限内容を確認するために有益になります:

// feel free to add more ini settings to this array if you are curious 
$to_check = array("max_execution_time", "memory_limit", "error_log"); 
foreach($to_check as $setting) { 
    echo $setting . ": " . ini_get($setting) . "\n<br>"; 
} 

これらの値が不十分で見れば、あなたのスクリプトでこれらの値を変更しようとしているいくつかの運を持っていることini_set またはを使用して、Webサーバーのphp.iniを編集します。スクリプトを長時間実行したりメモリを消費したりすると、サーバーはすべてのリソースを消費する可能性のあるスクリプトに対して脆弱になります。ただし、サーバーがsafe_modeで実行されている場合は、ini_setを使用して設定を変更することはできません。

私はまた、PHP関数のmemory_get_usage()とmicrotime()を見てみることをお勧めします。スクリプトで使用されたメモリと経過時間を追跡して、スクリプトが失敗する前にどのような値に達するかを知ることができます。おそらくスクリプトからこれらの値をエコーするほうが簡単ですが、それはおそらく良い考えではないでしょう。私はあなたがファイルに返された値を書くことをお勧めします。ような何か:

$log_file = "/some/path/to/log/file.txt"; 
$start_time = microtime(TRUE); // returns a unix timestamp as a float 
file_put_contents($log_file, "start time is " . $start_time) 
    or die("Unable to write log file"); 

// your script blah blah blah 
$file = fopen("data.csv", "r"); 
while (($datum = fgets($file)) !== False) { 

    // do your script datum stuff blah blah blah 

    // write our progress to our log file 
    file_put_contents($log_file, "elapsed time is " . (microtime(TRUE) - $start_time)) 
     or die("Unable to write elapsed time to log file"); 
    file_put_contents($log_file, "memory consumed is " . memory_get_usage()) 
     or die("Unable to write memory usage to log file"); 
} 

スクリプトが失敗した場合、あなたは /some/path/to/log/file.txt の内容を見て行くと、それが停止する前に使用されたどのくらいの時間とメモリを参照することができます。

+1

ありがとう!問題は時間だったし、ini_setを使って固定した。 – jmcampbell

+0

それはうまくいってうれしい! PHPには、[set_time_limit](http://php.net/set_time_limit)機能があります。 ini_setよりも少し表現力があります。 もう1つの一般的な経験則では、通常、コード実行のスピードアップにはより多くのメモリを使用できます。たとえば、十分なRAMがある場合は、file()またはfile_get_contents()を使用してファイル全体を一度に読み取ることができます。また、一度に1行を読むこともできますが、現在ははるかに少ないメモリを使用していますが、通常はもっと長い時間がかかります。 –

関連する問題