Non-blocking requests with php and curl not working with sleep

I have set up a small script to use the famous curl_multi_ * cUrl function to provide asynchronous non-blocking requests, this is a rough version of the code:

$mch = curl_multi_init();
$ch = curl_init();

url_setopt($ch, CURLOPT_URL,         $url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);          

curl_multi_add_handle($mch ,$ch);
$running = null;
do {
    curl_multi_exec($mch ,$running);
} while($running > 0);

curl_multi_remove_handle($mch,$ch);
curl_close($ch);

      

this is mainly used to send one request as a parallel request to allow the code to keep running and another script is called via cURL, I don't need the result so I didn't use any code to handle it. I just want another script that will be called while the code after the curl call continues.

First of all, I don't understand why I need a while loop, wouldn't it call multi_exec once for a single query to work? since no loop is used does not run script on $ url (i checked).

secondly, and my biggest problem is it must be asynchronous, I tried to put sleep (10) on another script, and the script call waits 10 seconds before continuing, I don’t understand that this should be non-blocking and should keep working ...

what am I doing wrong?

+2


source to share


2 answers


Let's start at the end.

When your PHP finishes with your script, it does cleanup and destroy any curl handles that are still running. It is important to remember this.

Now each swirl request is divided into several stages, for example, initializing the connection, connecting, writing data, reading data, closing the connection. Middle steps can be repeated. And I'm sure there are actually more complex things going on behind the scenes, but overall that description should be correct.

curl_multi_exec gives control to each of the descriptors in the multi-wheel and allows it to execute its next step, whatever it may be. And then the function will return.



This explains why you can't see a request without a loop. This is because your handle has not yet reached the step at which it can actually make the connection. Your PHP script exits, performs cleanup, which in turn kills the handle, which has no chance of doing anything.

So it is now clear that you need to give you the ability to do something. Running curl_multi_exec over and over is one way to achieve it.

This explains why you experience the wait, these multi-pens are not very asynchronous, they just look the way they are. Your loop gives you the option to start a handle and the loop will keep running until the request completes (which in your example takes 10 seconds).

Quick overview: you need to find another solution to your problem (to keep working with other code while curl is running) :)

+4


source


This works well for me:

function get_web_page( $url )
{
$options = array(
    CURLOPT_RETURNTRANSFER => true,     // return web page
    CURLOPT_HEADER         => false,    // don't return headers
    CURLOPT_FOLLOWLOCATION => true,     // follow redirects
    CURLOPT_ENCODING       => "",       // handle all encodings
    CURLOPT_USERAGENT      => "spider", // who am i
    CURLOPT_AUTOREFERER    => true,     // set referer on redirect
    CURLOPT_CONNECTTIMEOUT => 120,      // timeout on connect
    CURLOPT_TIMEOUT        => 120,      // timeout on response
    CURLOPT_MAXREDIRS      => 10,       // stop after 10 redirects
);

$ch      = curl_init( $url );
curl_setopt_array( $ch, $options );
$content = curl_exec( $ch );
$err     = curl_errno( $ch );
$errmsg  = curl_error( $ch );
$header  = curl_getinfo( $ch );
curl_close( $ch );

$header['errno']   = $err;
$header['errmsg']  = $errmsg;
$header['content'] = $content;
return $header;
}

      

As a function, you can call her back again and again. (as asynchronous streams). So all you have to do is write a while loop to handle and process all the curls you get. After that, your script can finish, avoiding stopping at the end of the code problem.

One more point .. you don't need to format your while loops like this.



do { ... } while (conditional)

      

you can just use:

while (conditional) { ... }

      

0


source







All Articles