5

I am using cURL's option for CURLOPT_WRITEFUNCTION to specify a callback to handle when data comes in from a cURL request.

$serverid=5;
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.whatever.com');
curl_setopt(
    $ch, 
    CURLOPT_WRITEFUNCTION, 
    function ($ch, $string) { 
        return readCallback($ch, $string, $serverid);
    }
);
curl_exec($ch);

function readCallback($ch, $string, $serverid) {
    echo "Server #", $serverid, "  |  ", $string;
    return strlen($string);
}

I want to use an anonymous function to call my own function that actuall does work (readCallback()) so that I can include the server ID associated with the request ($serverid). How can I properly utilize closures so that when cURL hits my callback anonymous function, that the anonymous function knows that it was originally defined with $serverid=5 and can call readCallback() appropriately?

I will eventually be using this with ParalellCurl and a common callback, which is why it is necessary to have an anonymous function call my callback with the ID.

1 Answer 1

7

If you would like to have access to $serverid inside your anonymous function, you have to tell PHP that you want to use that variable. Like this:

/*
 * I replaced the simple $serverid var to $serverIdHolder because
 * 'use' passes the variable by value, so it won't change inside
 * your anonymous function that way. But if you pass a reference
 * to an object, then you are able to see always the current needed value.
 */
$serverIdHolder = new stdClass;
$serverIdHolder->id = 5;

$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.whatever.com');
curl_setopt(
    $ch, 
    CURLOPT_WRITEFUNCTION, 
    function ($ch, $string) use ($serverIdHolder) { 
        return readCallback($ch, $string, $serverIdHolder->id);
    }
);
curl_exec($ch);

function readCallback($ch, $string, $serverid) {
    echo "Server #", $serverid, "  |  ", $string;
    return strlen($string);
}
Sign up to request clarification or add additional context in comments.

3 Comments

Excellent, thanks! Now, does use 'lock' that variable to the value it was at the time the anonymous function was defined? For example, I will eventually plan to call this in a loop, and the value of $serverid will change each iteration. If not, how can I create such a binding?
Thanks Imi for that clarification. By value is in fact what I needed, but I can think of times when the class reference would be useful as well. Excellent, thanks again!!
how do you achieve the opposite of this. I have a global var that I pass to the readCallback function. Inside the function the global var is updated. Then after curl is done, you should be able to read the global var and see the update that happened inside readCallback.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.