1

So, I want to create an asynchronous web service in PHP. Why? Because I've a nice async front-end, but Chrome will block my requests if I have more than 6 active TCP connections. Of course I have read some similar questions like:

but these don't cover my question.

I installed pthreads with the intention that I would be able to make multiple requests in different threads so that my PHP wasn't blocking other requests(in my situation I start eg. a long process and I want to be able to poll if the process is still busy or not).

PHPReact seems to be a nice library(non-blocking I/O, async) but this won't work either(still sync).

Am I missing something or is this nowadays still not possible in PHP?

class Example{
    private $url;   
    function __construct($url){
        $this->url = $url;
        echo 'pooooof request to ' . $this->url . ' sent <br />';
        $request = new Request($this->url);     
        $request->start();
    }
}

class Request extends Thread{
    private $url;   
    function __construct($url){
        $this->url = $url;
    }

    function run(){
        // execute curl, multi_curl, file_get_contents but every request is sync
    }
}

new Example('https://gtmetrix.com/why-is-my-page-slow.html');
new Example('http://php.net/manual/en/function.file-get-contents.php');
new Example('https://www.google.nl/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=php%20file%20get%20contents'); 

The ideal situation would be to make use of callbacks.

ps. I have seen some servers(like Node.js) that are providing this functionality, but I prefer a native approach. When this is not possible I'm really thinking of switching to Python, Java, Scala or some other language that supports async.

Community
  • 1
  • 1
GuyT
  • 4,316
  • 2
  • 16
  • 30
  • You are surely missing something, but the question is unclear ... it sounds like you want to handle *incoming* requests asynchronously, yet the example shows you trying to spawn simultaneous *outgoing* requests. – Narf Aug 12 '15 at 08:33
  • @Narf I want to handle both asynchronously. Just to explain my current situation: I've a JavaScript front-end, some kind of a PHP interface/controller to communicate with Java webservices. So my front-end will send a request to my PHP controller and this controller will send a request to the Java services. Of couse I don't want that a call blocks my other calls till I receive a response. So, when my PHP controller receives a request this has to be send to the webservice, but I don't want to wait for the response and handle other requests. When I get a response I want to be notified. – GuyT Aug 12 '15 at 08:43
  • That's actually two questions then, but I'll only comment on the JS->PHP part now ... Waiting for a response on one request shouldn't block other simultaneous requests. If it does, then that's due to a browser limitation, hitting a server-side max_requests limit or something unrelated in your PHP logic (e.g. a session can do that). There are of course ways to work around these conditions, but it's a very broad topic ... – Narf Aug 12 '15 at 09:15
  • @Narf Are you sure? By default PHP is single threated.. – GuyT Aug 12 '15 at 11:58
  • It is single threaded, but you don't need threads at all because the httpd (by default) spawns separate processes. In fact, 99% of the time you think threads are the solution, procs are the better solution. – Narf Aug 12 '15 at 12:17
  • @Narf So why is eg. `cURL` synchronous? You have to wait till the response before any other code is executed. – GuyT Aug 12 '15 at 12:22
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/86787/discussion-between-narf-and-guyt). – Narf Aug 12 '15 at 12:35

1 Answers1

3

I can't really make sense of what you are doing ...

  • Asynchronous and Parallel are not interchangeable words.
  • Threads at the frontend of a web application don't make sense.
  • You don't need threads to make many I/O bound tasks concurrent; That is what non-blocking I/O is for (asynchronous concurrency).
  • Parallel concurrency seems like overkill here.

Regardless, the reason your requests appear synchronous is the way this constructor is written:

function __construct($url){
    $this->url = $url;
    echo 'pooooof request to ' . $this->url . ' sent <br />';
    $request = new Request($this->url);     
    $request->start();
}

The Request thread will be joined before control is returned to the caller of __construct (new) because the variable goes out of scope, and so is destroyed (joining is part of destruction).

Joe Watkins
  • 17,032
  • 5
  • 41
  • 62
  • First of all thank you for your answer. You've made some really nice libraries! I've tried to clear things up: http://imgur.com/nH2KEcy . 1) JavaScript is executing a `POST` request to a PHP file(eg. `webservice.php?method=blabla`, multiple requests simultaneously). 2) PHP controller will invoke a Java web service. 3) Only after the first long running process has finished, the other requests will invoke the Java web service.. So, that's why I think that PHP is blocking the requests. – GuyT Aug 13 '15 at 11:38
  • Ohh.. and I've read your post and now I'm realizing that I've mixed things up. Your diagrams about the difference between asynchronous and parallel are very clear. Thank you for that. – GuyT Aug 13 '15 at 11:50