2011-09-09 15 views
4

PHPのメモリ使用量を変更できない共有ホスティング環境で実行されているスクリプトがあります。このスクリプトは、SOAPを介してWebサービスを使用しています。一度にすべてのデータを取得することはできません。そうでなければメモリが不足しているので、mysqlデータベースにローカルでデータをキャッシュすることで成功し、その後のクエリが高速になります。ループ内のメモリを「解放する」方法は?

基本的に、Webサービスに5か月のデータを照会するのではなく、1か月に1回クエリを実行してmysqlテーブルに格納し、次の月などを取得します。これは通常動作しますが、 。

私の基本的なコードのロジックは、このようなものです:

  1. 石鹸を使用してWebサービスに接続します。
  2. mysqlデータベースに接続
  3. 結果Webサービスと結果を変数$ resultsに格納します。
  4. mysqlのテーブルに
  5. ダンプ$結果
  6. 繰り返しは、私は、Webサービスからの結果の各バッチがあろうと仮定しますので、同じ変数は各反復で使用されているデータ

の各月の3と4ステップ前のメモリを上書きする?私は反復の間にunset($ results)を使ってみましたが、何もしませんでした。私は毎回memory_get_usage(true)で使用されるメモリを出力しており、使用されるメモリが増えるごとに繰り返します。

どのように私はこのメモリリークを修正できますか?私は十分に明確でない場合はコメントを残し、私は詳細を提供することができます。ありがとう!

*** EDITここ

は(それが違いを作る場合、私はPHP5のネイティブのSOAPクライアントをnusoapない使用しています)いくつかのコードです:

$startingDate = strtotime("3/1/2011"); 
$endingDate = strtotime("7/31/2011"); 
// connect to database 
mysql_connect("dbhost.com", "dbusername" "dbpassword"); 
mysql_select_db("dbname"); 
// configure nusoap 
$serverpath ='http://path.to/wsdl'; 
$client = new nusoap_client($serverpath); 
// cache soap results locally 
while($startingDate<=$endingDate) { 
    $sql = "SELECT * FROM table WHERE date >= ".date('Y-m-d', $startingDate)." AND date <= ".date('Y-m-d', strtotime($startingDate.' +1 month')); 
    $soapResult = $client->call('SelectData', $sql); 
    foreach($soapResult['SelectDateResult']['Result']['Row'] as $row) { 
     foreach($row as &$data) { 
      $data = mysql_real_escape_string($data); 
     } 
     $sql = "INSERT INTO table VALUES('".$row['dataOne']."', '".$row['dataTwo']."', '".$row['dataThree'].")"; 
     $mysqlResults = mysql_query($sql); 
    } 
    $startingDate = strtotime($startingDate." +1 month"); 
    echo memory_get_usage(true); // MEMORY INCREASES EACH ITERATION 
} 
+0

これまでのアイデアはありません。いくつかのコードを貼り付けてみてください。 – fiunchinho

答えて

5

解決しました。少なくとも部分的に。 nusoapを使用してメモリリークが発生しています。 Nusoapはデバッグログを$ GLOBALS変数に書き込みます。 nusoap.phpでこの行を変更すると、たくさんのメモリが解放されました。

変更

$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9; 

$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 0; 

に私はPHP5のネイティブSOAPクライアントを使用することを好むだろうが、私は私がしようとしているWebサービスに固有のものと考えている奇妙な結果を取得しています消費する。 www.mindbodyonline.comのSOAP APIでphp5のSOAPクライアントを使用することに慣れている人は、私に知らせてください。

+0

今後この種の問題にはxhprofを使用できます。 – chelmertz

+0

hh。とても興味深い。ニースを見つける!私はこのようなものを見つけることができなかったので、人々はこの答えを相互参照することを願っています。私はグローバルをチェックすることを知っていたはずです。 –

+0

ありがとうございます。なぜ私のPHPスクリプトの1つが500MB以上のメモリを使用していたのかを判断しようとするのは、ほぼ3日間を費やした後、私の救い主でした。これはまさに問題でした。また、PHP5のネイティブSOAPクライアントにも問題があります。なぜなら、WSDLに基づいて私が明らかに提供していたフィールドを提供していないというエラーが出てしまったからです。 – Ricky

-1

あなたは$ startingDateとmysql_free_result()unset()を試してみました$ mysqlResultsのために?

また、SELECT *は、ここで問題が発生していなくても悩んでいます。

EDIT:おそらくSOAP結果も解放してください。それが役立つかどうかを確認するために始めるべきいくつかの簡単なもの。

+0

mysql_free_result()はINSERTクエリでは機能せず、$ startingDate、$ sql、$ mysqlResults、$ row、$ data、$ soapResultの各変数の設定を解除しようとしましたが、メモリ使用量は変更されません。 –

+0

Huh。他の人たちもあなたの問題を抱えているように見えます。 http://www.php.net/manual/en/ref.soap.php#52758実際のメモリ豚のようです。私はそれほど多くの、ほとんどRESTfulなサービスをJSONに提供するSOAPを消費したことはありません。そのような代替手段はありません、ありますか? –

+0

しかし、まずSOAPサーバーからSELECT *を実行しないでください。おそらくここでは役に立たないでしょう。 –

関連する問題