Error handler php curl multi error

I want to fix errors and warnings in my error handler so that they don't get echo ed to the user. to prove that all errors were caught, I add the line $err_start to the error. this is currently a working (but simplified) snippet of my code (run it in a browser, not cli):

 <?php set_error_handler('handle_errors'); test_curl(); function handle_errors($error_num, $error_str, $error_file, $error_line) { $err_start = 'caught error'; //to prove that the error has been properly caught die("$err_start $error_num, $error_str, $error_file, $error_line<br>"); } function test_curl() { $curl_multi_handle = curl_multi_init(); $curl_handle1 = curl_init('iamdooooooooooown.com'); curl_setopt($curl_handle1, CURLOPT_RETURNTRANSFER, true); curl_multi_add_handle($curl_multi_handle, $curl_handle1); $still_running = 1; while($still_running > 0) $multi_errors = curl_multi_exec($curl_multi_handle, $still_running); if($multi_errors != CURLM_OK) trigger_error("curl error [$multi_errors]: ".curl_error($curl_multi_handle), E_USER_ERROR); if(strlen(curl_error($curl_handle1))) trigger_error("curl error: [".curl_error($curl_handle1)."]", E_USER_ERROR); $curl_info = curl_getinfo($curl_handle1); //info for individual requests $content = curl_multi_getcontent($curl_handle1); curl_multi_remove_handle($curl_multi_handle, $curl_handle1); curl_close($curl_handle1); curl_multi_close($curl_multi_handle); } ?> 

Please note that my complete code has several queries in parallel, however, the problem still appears in one query, as shown here. note also that the error handler shown in this code snippet is very simple - my actual error handler will not die on warning or notifications, so I don’t need to train me on this.

now, if I try and twist a host that is currently unavailable, I successfully fix the curl error and my script dies with

 caught error 256, curl error: [Couldn't resolve host 'iamdooooooooooown.com'], /var/www/proj/test_curl.php, 18 

however, the following warning does not fall into my error handler function and on the echo ed page:

 Warning: (null)(): 3 is not a valid cURL handle resource in Unknown on line 0 

I would like to fix this warning in my error handler so that I can register it for later control.

One thing I noticed is that the warning only appears when the curl code is inside the function - it does not happen when the code is at the highest level of visibility. Is it possible that one of the curved globals (for example, CURLM_OK ) is not available within the test_curl() function?

I am using PHP Version 5.3.2-1ubuntu4.19

edits

  • updated the code snippet to fully demonstrate the error.
  • an unprotected warning appears only if inside a function or class method
+4
source share
2 answers

I don’t think I agree with how you fix the error ... you can try

 $nodes = array( "http://google.com", "http://iamdooooooooooown.com", "https://gokillyourself.com" ); echo "<pre>"; print_r(multiplePost($nodes)); 

Output

 Array ( [google.com] => #HTTP-OK 48.52 kb returned [iamdooooooooooown.com] => #HTTP-ERROR 0 for : http://iamdooooooooooown.com [gokillyourself.com] => #HTTP-ERROR 0 for : https://gokillyourself.com ) 

Function used

 function multiplePost($nodes) { $mh = curl_multi_init(); $curl_array = array(); foreach ( $nodes as $i => $url ) { $url = trim($url); $curl_array[$i] = curl_init($url); curl_setopt($curl_array[$i], CURLOPT_RETURNTRANSFER, true); curl_setopt($curl_array[$i], CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)'); curl_setopt($curl_array[$i], CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($curl_array[$i], CURLOPT_TIMEOUT, 15); curl_setopt($curl_array[$i], CURLOPT_FOLLOWLOCATION, true); curl_setopt($curl_array[$i], CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($curl_array[$i], CURLOPT_SSL_VERIFYPEER, 0); curl_multi_add_handle($mh, $curl_array[$i]); } $running = NULL; do { usleep(10000); curl_multi_exec($mh, $running); } while ( $running > 0 ); $res = array(); foreach ( $nodes as $i => $url ) { $domain = parse_url($url, PHP_URL_HOST); $curlErrorCode = curl_errno($curl_array[$i]); if ($curlErrorCode === 0) { $info = curl_getinfo($curl_array[$i]); $info['url'] = trim($info['url']); if ($info['http_code'] == 200) { $content = curl_multi_getcontent($curl_array[$i]); $res[$domain] = sprintf("#HTTP-OK %0.2f kb returned", strlen($content) / 1024); } else { $res[$domain] = "#HTTP-ERROR {$info['http_code'] } for : {$info['url']}"; } } else { $res[$domain] = sprintf("#CURL-ERROR %d: %s ", $curlErrorCode, curl_error($curl_array[$i])); } curl_multi_remove_handle($mh, $curl_array[$i]); curl_close($curl_array[$i]); flush(); ob_flush(); } curl_multi_close($mh); return $res; } 
+7
source

it is possible that this is a bug with php-curl. when the next line is deleted, then everything behaves normally:

 if(strlen(curl_error($curl_handle1))) trigger_error("curl error: [".curl_error($curl_handle1)."]", E_USER_ERROR); 

as far as I can tell, curl with the host down is distorting $curl_handle1 because the curl_error() function is not ready. to work around this problem (before fixing the error), just check if http_code to curl_getinfo() 0 . if it is 0 , then do not use the curl_error function:

 if($multi_errors != CURLM_OK) trigger_error("curl error [$multi_errors]: ".curl_error($curl_multi_handle), E_USER_ERROR); $curl_info = curl_getinfo($curl_handle1); //info for individual requests $is_up = ($curl_info['http_code'] == 0) ? 0 : 1; if($is_up && strlen(curl_error($curl_handle1))) trigger_error("curl error: [".curl_error($curl_handle1)."]", E_USER_ERROR); 

this is not a very elegant solution, but it may need to be done now.

+1
source

All Articles