[PHP-users 28997] Re: curl関数によるデータ収集について
Reiji Matsumoto
matsumoto @ spline.oc.to
2006年 4月 13日 (木) 17:09:06 JST
松本と申します。
> ある程度動くものが作られ、一定の成果を得ているのですが、かなり高い確立で
> プログラムの途中で応答なしの状態になってしまい、実行が中断されてしまうとい
う
> 現象に
> 悩まされております。
一般的な話しになりますが、phpを精々数秒で処理が完結するwebページ表示用の
スクリプトでは無く、処理が数時間に及ぶコマンドライン起動のスクリプトと
して利用するような場合、それなりにメモリに注意を払わないとまずい
です。phpは基本的にリークはしませんが、スクリプトが終わるまでどんどん
メモリが消費されてしまうという事があります。その結果利用可能メモリが
無くなり、予期せぬ結果になってしまったりする事があります。
また、組み込まれているリソース確保型の関数群も、一回のメソッド発行で破棄
される、使い捨て的な利用方法を前提にしている場合があり、phpにおけるcurl
の実装にも、そのような側面があります。
つまり、
>
> $ch = curl_init();
> curl_setopt($ch, CURLOPT_URL, $url);
> curl_setopt($ch, CURLOPT_USERAGENT, $global_values["user_agent"]);
> curl_setopt($ch, CURLOPT_TIMEOUT, 10);
> curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
> $html = curl_exec($ch);
> curl_close($ch);
>
上記プログラムは当然抜粋だと思いますが、本件ではループの中に置かれて
いると思います。その際、ループの中でcurl_init()とcurl_close()を繰り返す
構造になっているでしょうか。例えば
while(条件) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERAGENT, $global_values["user_agent"]);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$html = curl_exec($ch);
curl_close($ch);
}
このような構造でしょうか。これならば問題ありませんが、
$ch = curl_init();
while(条件) {
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERAGENT, $global_values["user_agent"]);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$html = curl_exec($ch);
}
curl_close($ch);
このような構造になっていると、curl_exec()を実行するたびに少しずつ解放
されないメモリが蓄積されていき、いずれ動かなくなります。
私は php-4.3.x + linux + curl-7.10.4 で、この問題に遭遇しました。
OS含めご利用中の環境と大分違うようですので、参考にならなかったらごめんなさ
い。
PHP-users メーリングリストの案内