Modify Parallel Curl code to allow user data to be passed by reference

I’m using Parallel Curl https://github.com/petewarden/ParallelCurl to make a bunch of my server to another server requests.

It has the facility to include $user_data in the call to Parallel Curl and the call back, so that in your function that handles results you can have your user data available in the scope of that function. Fine. But I want that user data to behave like global data. That is when I modify its contents I want those changes to stick throughout all the code, multiple Parallel Curl uses, multiple handle results function runs.

In Parallel Curl’s code there’s:


...
    public function startRequest($url, $callback, $user_data = array(), $post_fields=null) {


		if( $this->max_requests > 0 )
...

I tried modifying Parallel Curl’s code like so: … &$user_data = array() … but that didn’t do it. The modifications to my user data isn’t sticking. Any suggestions? Thanks.

More info:

my code:


$my_user_data = array( ..., '...' => array(...) );


...


$parallel_curl = new ParallelCurl($max_requests, $curl_options);


foreach ( ... ) {
    $parallel_curl->startRequest($url, 'on_request_done', $my_user_data);
}


...


function on_request_done($content, $url, $ch, $my_user_data) {
    
    // here I modify various values in $my_user_data
    
}




$parallel_curl->finishAllRequests();


// Here I want to use $my_user_data with all the modifications made from within on_request_done() being accessible.
// At the moment, they're not.

Parallel Curl’s code:

class ParallelCurl {    
    ...


    public $outstanding_requests;
    
    ...
    
    public function __construct($in_max_requests = 10, $in_options = array()) {
        ...
        $this->outstanding_requests = array();
        ...
    }
    
    ...
    
    public function startRequest($url, $callback, $user_data = array(), $post_fields=null) {
    
        ...


        $this->outstanding_requests[$ch_array_key] = array(
            'url' => $url,
            'callback' => $callback,
            'user_data' => $user_data,
        );
        
        ...
    }
    
    ...
    
    // Checks to see if any of the outstanding requests have finished
    private function checkForCompletedRequests() {
    
        ...
        
        // Now grab the information about the completed requests
        while ($info = curl_multi_info_read($this->multi_handle)) {
        
            ...
            
            $request = $this->outstanding_requests[$ch_array_key];


            $url = $request['url'];
            $content = curl_multi_getcontent($ch);
            $callback = $request['callback'];
            $user_data = $request['user_data'];
            
            call_user_func($callback, $content, $url, $ch, $user_data);
            
            unset($this->outstanding_requests[$ch_array_key]);
            
            curl_multi_remove_handle($this->multi_handle, $ch);
        }
    
    }
    
    ...


}

So how can I have it so there’s one version, not copies of, my user data (named $my_user_data in my code, and $user_data and part of $outstanding_requests in Parallel Curl’s code) throughout? (Editing Parallel Curl’s code is fine.)

Thanks.

I think I’ve found the (or at least one) reason this isn’t working.

In the manual for call_user_func():

Note that the parameters for
call_user_func()[COLOR=#000000][FONT=verdana] are not passed by reference.

[/FONT][/COLOR]That would do it; stop it working that is.

I’ve done a toy/test version. How to get this to work?:

class Test {
	
	public $an_array;
	public $a_function;
	
	public function __construct(&$an_array, $function) {
		$this->an_array = $an_array;
		$this->a_function = $function;
	}
	
	public function test() {
		for( $i=0; $i < 100; $i++ ) {
			call_user_func($this->a_function, $this->an_array);
		}
	}
	
}


function my_callback(&$an_array) {
	$an_array['value']++;
}


$an_array = array('value'=>1);


$t = new Test($an_array, 'my_callback');


$t->test();


echo '<textarea rows="20" cols="50">';
print_r($an_array); // the value in the array should be a 100 or something, not 1 at this point
echo '</textarea>';

So I want the modifications of the value in the array in the callback function to stick; to be accessible at the end of the code. How? Thanks.

And the issue I pointed out about call_user_func() not passing by reference, I’m thinking that isn’t it actually, because I think the variable already holds a reference, and I don’t want to pass a reference to a reference I don’t think. Not sure.

This works:

class Test {	
	public function __construct(&$an_array, $function) {
		for( $i=0; $i < 100; $i++ ) {
			call_user_func_array($function, array(&$an_array));
		}
	}
	
}


function my_callback(&$an_array) {
	$an_array['value']++;
}


$an_array = array('value'=>1);


$t = new Test($an_array, 'my_callback');


echo '<textarea rows="20" cols="50">';
print_r($an_array); // the value in the array should be a 100 or something, not 1 at this point
echo '</textarea>';

It never stores the array as an object variable. But I need to. Using the same kind of fix above but storing the array as an object variable stops is working:

class Test {
	
	public $an_array;
	public $a_function;
	
	public function __construct(&$an_array, $function) {
		$this->an_array = $an_array;
		$this->a_function = $function;
	}
	
	public function test() {
		for( $i=0; $i < 100; $i++ ) {
			call_user_func_array($this->a_function, array(&$this->an_array));
		}
	}
	
}


function my_callback(&$an_array) {
	$an_array['value']++;
}


$an_array = array('value'=>1);


$t = new Test($an_array, 'my_callback');


$t->test();


echo '<textarea rows="20" cols="50">';
print_r($an_array); // the value in the array should be a 100 or something, not 1 at this point
echo '</textarea>';

Nearly, but still not there. Need to be able to store array as object variable. Any ideas? Thanks.

OK, finally got it. That last bit of code with this modification does it:

$this->an_array = &$an_array;