SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    SitePoint Wizard
    Join Date
    Apr 2002
    Posts
    2,307
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    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:
    Code:
    ...
        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.

  2. #2
    SitePoint Wizard
    Join Date
    Apr 2002
    Posts
    2,307
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    More info:

    my code:
    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:
    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.

  3. #3
    SitePoint Wizard
    Join Date
    Apr 2002
    Posts
    2,307
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    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() are not passed by reference.

    That would do it; stop it working that is.

  4. #4
    SitePoint Wizard
    Join Date
    Apr 2002
    Posts
    2,307
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    I've done a toy/test version. How to get this to work?:

    Code:
    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.

  5. #5
    SitePoint Wizard
    Join Date
    Apr 2002
    Posts
    2,307
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    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.

  6. #6
    SitePoint Wizard
    Join Date
    Apr 2002
    Posts
    2,307
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    This works:
    Code:
    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:

    Code:
    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.

  7. #7
    SitePoint Wizard
    Join Date
    Apr 2002
    Posts
    2,307
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    OK, finally got it. That last bit of code with this modification does it:

    $this->an_array = &$an_array;


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •