これらの投稿で提案されているように、cURL 応答を制限しようとしています: Retrieve partial web page and PHP CURLOPT_WRITEFUNCTION does not appear to be working . アイデアは、コールバック関数で指定されているように、応答を 4000 文字に制限することです。
私は次の関数を書きましたが、コールバック関数定義のパラメーターは関数呼び出し内のようにループ内で変化しないため、意味がないことは既にわかっています。関数が実際に呼び出されるまでに、$key の値は固定されているため、そのインデックスへの参照は変化しません。
ループごとに新しいクロージャー関数が必要なようで、それぞれが独自の $full_length 変数を参照する必要があります。しかし、それがどのように可能かわかりません。そのためには、特定の $full_length 変数を指定するために、どうにかしてクロージャー オブジェクトへの参照を作成する必要があるようです。
どんな助けでも大歓迎です。ありがとう。
function get_headers($urls){
$curly = array();
$result = array();
$mh = curl_multi_init();
$obj = $this;
foreach ($urls as $key => $url) {
$this->full_length[$key] = 0;
$callback = function ($ch, $string) use ($obj, $key){
$length = strlen($string);
$obj->full_length[$key] += $length;
if($obj->full_length[$key] >= 4000){
return -1;
}
return $length;
};
$curly[$key] = curl_init
curl_setopt($curly[$key], CURLOPT_URL, $url);
curl_setopt($curly[$key], CURLOPT_HEADER, 0);
curl_setopt($curly[$key], CURLOPT_WRITEFUNCTION, $callback);
curl_setopt($curly[$key], CURLOPT_RETURNTRANSFER, 1);
curl_multi_add_handle($mh, $curly[$key]);
}
$running = null;
do {
curl_multi_exec($mh, $running);
} while($running > 0);
foreach($curly as $key => $cnt) {
$content = curl_multi_getcontent($cnt);
curl_multi_remove_handle($mh, $cnt);
if (strlen($content) > 0){
$result[$key] = $content;
} else {
curl_multi_close($mh);
return FALSE;
}
}
curl_multi_close($mh);
return $result;
}
編集:
私がやろうとしていることを正確に行う投稿を見つけましたが、それは javascript にあります: for loop - callback with loop variable as parameterです。PHP で同じことを行うために、次の関数を作成しました。
function get_write_function($key){
$this->full_length[$key] = 0;
$obj = $this;
$funky = function ($ch, $str) use ($obj, $key){
$length = strlen($str);
$obj->full_length[$key] += $length;
if($obj->full_length[$key] >= 4000){
return -1;
}
return $length;
};
return $funky;
}
コードはエラーなしで実行されましたが、それでも私が望んでいたことはできませんでした。cURL ハンドルを閉じた後、$full_length 配列をダンプしましたが、次のようにしか表示されませんでした。
array([0] => 0, [1] => 0)
これは、get_write_function によって初期化された (クラス宣言で何も初期化していないため) ことを示していますが、値はその後更新されていません。