[英]Parallel cURL Request with WRITEFUNCTION Callback
我試圖按照這些帖子中的建議限制我的cURL響應: 檢索部分網頁 , PHP CURLOPT_WRITEFUNCTION似乎不起作用 。 想法是將響應限制為回調函數中指定的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變量作為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初始化的(因為我沒有在類聲明中初始化任何東西),但是之后從未更新這些值。
我終於明白了。 最大的問題是cURL一直忽略WRITEFUNCTION,直到我將其放置為指定的最后一個選項為止,正如我在此處發布的內容: cURL WRITEFUNCTION not被調用 。 實際上,我不需要返回轉移,因為我將輸出寫入了一個類變量。 這是必要的,因為當回調返回-1時,什么也不會返回。 以下代碼效果很好:
var $full_length = array();
var $result = array();
function get_headers($urls){
$curly = array();
$mh = curl_multi_init();
foreach ($urls as $key => $url) {
$callback = $this->get_write_function($key);
$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_multi_add_handle($mh, $curly[$key]);
}
$running = null;
do {
curl_multi_exec($mh, $running);
} while($running > 0);
foreach($curly as $key => $cnt) {
curl_multi_remove_handle($mh, $cnt);
}
curl_multi_close($mh);
return $this->result;
}
function get_write_function($key){
$this->full_length[$key] = 0;
$this->result[$key] = '';
$obj = $this;
$funky = function ($ch, $str) use ($obj, $key){
$obj->result[$key] .= $str;
$length = strlen($str);
$obj->full_length[$key] += $length;
if($obj->full_length[$key] >= 4000){
return -1;
}
return $length;
};
return $funky;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.