标签云

微信群

扫码加入我们

WeChat QR Code

Is there a way in PHP to make asynchronous HTTP calls? I don't care about the response, I just want to do something like file_get_contents(), but not wait for the request to finish before executing the rest of my code. This would be super useful for setting off "events" of a sort in my application, or triggering long processes.Any ideas?


one function - 'curl_multi', look in the php docs for it. Should solve your problems

2019年04月22日12分49秒

The title of this post is misleading. I came looking for truly asynchronous calls similar to requests in Node.js or an AJAX request. The accepted answer isn't async (it blocks and doesn't provide a callback), just a faster synchronous request. Consider changing the question or accepted answer.

2019年04月22日12分49秒

Playing with connection handling via headers and buffer is not bulletproof. I have just post a new answer independant from OS, browser or PHP verison

2019年04月23日12分49秒

Asynchronous does not mean you don't care about the response. It just means the call doesn't block the main thread execution. Asynchronous still requires a response, but the response can beprocessed in another thread of execution or later in an event loop. This question is asking for a fire-and-forget request which can be synchronous or asynchronous depending on message delivery semantics, whether you care about message order, or delivery confirmation.

2019年04月22日12分49秒

I think you should make this fire HTTP request in non-blocking mode (w/c is what you really want).. Because when you call a resource, you basically want to know if you reached the server or not (or whatever reason, you simply need the response). The best answer really is fsockopen and setting stream reading or writing to non-blocking mode. It's like call and forget.

2019年04月22日12分49秒

If you look at the link you posted here, my answer includes a way to do GET requests as well.

2019年04月23日12分49秒

This is NOT async! In particular if the server on the other side is down this piece of code will hang for 30 seconds (the 5th parameter in the fsockopen). Also the fwrite is going to take its sweet time to execute (that you can limit with stream_set_timeout($fp, $my_timeout). The best you can do is to set a low timeout on fsockopen to 0.1 (100ms) and $my_timeout to 100ms. You risk though, that the request timeout.

2019年04月22日12分49秒

I assure you that it is async, and does not take 30 seconds. That's a timeout max. It's feasible that your settings are different causing that effect, but this worked great for me.

2019年04月22日12分49秒

UltimateBrent There's nothing in the code that suggests it's asynchronous. It doesn't wait for a response, but that is not asynchronous. If the remote server opens the connection and then hangs, this code would wait for 30 seconds until you hit that timeout.

2019年04月22日12分49秒

the reason that it seems to work "async" because you don't read from the socket before closing it so it didn't hang even if the server did not emit a response in time. However this is absolutely not async. If the write buffer is full (very least likely) your script will definitely hang there. You should consider changing your title to something like "requesting a webpage without waiting for response".

2019年04月22日12分49秒

This would work. But if you are using a MVC framework it may be difficult to implement because the way that these framework intercept and rewrite calls. For example it does not work in a Controller in CakePHP

2019年04月22日12分49秒

A doubt about this code, the process you need to do in longtask must go after this lines? Thanks.

2019年04月22日12分49秒

morgar: Yes, you are correct.

2019年04月22日12分49秒

Is this the best solution for asynchronously running a .php file on the SAME site?

2019年04月22日12分49秒

how are you wanting to call it? via the web (ie this method) or run it locally (eg like an include()) either way this is easy.running exec('php /path/to/file.php &'); (ie with the &) will work. But calling it via the web interface is safer (and more likely to work .. especially with file permissions and safemode restrictions)

2019年04月22日12分49秒

It does not works when the parent script got finished so it is not useful.

2019年04月22日12分49秒

Seriously ? this is not asynchronous at all, the process will WAIT until every call to fopen() returns! . loop in 50 urls and the script will take 50 * timeTo1URL times $time1 = microtime(true); for($x = 0; $x < 50; $x++){ do_post_request("https://www.example.com", "",null,false); } echo microtime(true) - $time1; exit;

2019年04月22日12分49秒

Similarly, I've also done the following: exec("curl $url > /dev/null &");

2019年04月22日12分49秒

Question: is there a benefit of calling 'bash -c "wget"' rather than just 'wget'?

2019年04月22日12分49秒

In my testing, using exec("curl $url > /dev/null 2>&1 &"); is one of the fastest solutions here.It's immensely faster (1.9s for 100 iterations) than the post_without_wait() function (14.8s) in the "accepted" answer above.AND it's a one-liner...

2019年04月22日12分49秒

Use full path (e.g. /usr/bin/curl) to make it even more faster

2019年04月22日12分49秒

This is not asyncronous because exec is blocking until you quit or fork the process you want to run.

2019年04月22日12分49秒

Did you notice the & at the end?

2019年04月22日12分49秒

So would this block the script then or not, im confused?

2019年04月23日12分49秒

pleshy it won't. ampersand (&) means to run the script in background

2019年04月22日12分49秒

However, this answer its not asynchronous.apparently guzzle doesn't do that

2019年04月22日12分49秒

Guzzle requires you to install curl. Otherwise it is non-parallel, and it doesn't give you any warning that it's non-parallel.

2019年04月22日12分49秒

Thanks for the link daslicious - yes, it appears it's not completely async (as in when you want to send off a request but don't care about the result) but a few posts down in that thread a user has offered a workaround by setting a very low request timeout value which still permits the connection time, but doesn't wait for the result.

2019年04月22日12分49秒

How do you handle connection time out (resolve, dns)? When I set timeout_ms to 1 I always end up with "resolving timed out after 4 ms" or something like that

2019年04月22日12分49秒

I don't know but 4 ms sounds already pretty fast to me... I don't think you can resolve faster by changing any curl settings. Try optimizing the targeted request perhaps...

2019年04月22日12分49秒

Ok, but timeout_ms=1 sets the timeout for the whole request. So if your resolve takes more than 1ms, then curl will timeout and stop the request. I don't see how this can work at all (assuming resolve takes >1 ms).

2019年04月22日12分49秒

This should be the accepted answer to the question because, even if it's not true async, it's better than the accepted one and all "async" answers with guzzle (Here you can perform operations while the request is performed)

2019年04月22日12分49秒

Please note that many hosting providers do not allow usage of certain PHP functions (like popen/exec). See disable_functions PHP directive.

2019年04月22日12分49秒

Requires lib pthreads and zend thread safety.

2019年04月22日12分49秒

It only put a cap thought a timeout. It is not async at all.

2019年04月22日12分49秒