2

これらの投稿で提案されているように、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 によって初期化された (クラス宣言で何も初期化していないため) ことを示していますが、値はその後更新されていません。

4

1 に答える 1