2013-04-09 62 views
2

我想限制我的cURL響應,建議在這些帖子中:Retrieve partial web pagePHP CURLOPT_WRITEFUNCTION doesn't appear to be working。這個想法是將回應限制在回調函數中指定的4000個字符。具有WRITEFUNCTION並行cURL請求回調

我寫了下面的函數,但我已經知道它沒有意義,因爲回調函數定義中的參數在函數調用中不會在循環內發生變化。在實際調用函數時,$ 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: closure inside a 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; 
} 

的代碼運行沒有錯誤,但它仍然沒有做什麼,我想要的。收盤後,我的捲曲處理我甩了$ full_length陣列,它只是表明:

array([0] => 0, [1] => 0) 

這表明它們是由get_write_function初始化(因爲我沒有初始化類聲明的任何東西),但該值之後從未更新。

回答

1

我終於明白了。最大的問題在於cURL忽略了WRITEFUNCTION,直到我將它作爲最後一個選項指定,因爲我發佈在這裏:cURL WRITEFUNCTION not Being Called。我實際上不需要返回傳輸,因爲我將輸出寫入類變量。這是必要的,因爲當回調返回-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; 
}