PHP: how does http_get work? - php

Let's say I have an index.php where I use some form of http get/post operation. How exactly is this executed by the server? does it pause and wait for a response before completing execution? What if nothing is returned? What if I want the execution to continue and another script to be executed once the response arrives (as in Ajax)?
enlightenment appreciated.

It's a simple matter of logic.
Does it pause and wait for a response before completing execution?
Yes.
What if nothing is returned?
Then you either get false or a empty string.
What if I want the execution to continue and another script to be executed once the response arrives (as in Ajax)?
You need to play with libevent (not for the soft-hearted - a lot harder than Ajax).

Server receives the request (let's say it's Apache), it recognizes someone is requesting a .php file so it knows it has to pass the request to PHP engine. PHP engine receives the request and parses the headers into $_POST / $_GET / $_FILES ($_REQUEST) superglobals so that it can be worked with.
During this time the execution is as follows:
Client requests a resource from the server.
Server receives it and does certain work to return response (in this case it invokes PHP engine).
PHP engine does what it has to do and returns a result (be it a valid result or a parse error - server doesn't care). In any way, if nothing went wrong server will return a response with appropriate response status code (2xx, 3xx, 4xx, 5xx, you probably know of 404 already).
Once Apache receives response from PHP, script execution is stopped.
It's not full-duplex communication where you can have socket open at all times to be used as a telephone wire (think Skype or any other IM).
In case of Javascript and async calls - since JS is asynchronous language (it implements an event loop rather than threaded model), you specify a callback function to be executed when the response arrives. Depending on what you need, you can send yet another request to the server.
However, there's the WebSocket protocol that enables full-duplex communication which leaves the connection open and where server can push the data to the client. It requires a different server than Apache / Nginx such as Node.js or a custom one.

Reading from the docs, it seems like http_get is a blocking call, i.e. it will freeze your script until the HTTP transaction completes, fails or timeouts. It seems like you cannot set it in non-blocking mode, and PHP has no threads. I'm not an expert in PHP, but I think there's no easy way to continue the script.
Besides the question itself, if I were you, I would really reconsider my choices. I feel like you're not thinking it the right way, because I can hardly imagine a scenario where it's strictly needed to perform an HTTP GET in PHP. It is done very, very rarely.

PHP scripts do not continue running in any fashion unless the page is still being passed to the browser. If your browser's "Loading" icon isn't spinning, then PHP has stopped being executed. They run and then terminate almost instantaneously (for reasonably-sized pages).
When you pass an HTTP GET/POST signal, you're passing it to a PHP script, but not one that is already running and waiting for a response. It's an entirely new instantiation of the script, which has to re-assign everything, re-include everything, and re-grab everything from the database, if you're using one.

The index.php will be executed and terminated right away.
If there's a request post to the php, the php file will be executed (again, if it's index.php) and terminated.
You can use exec() function to execute your script in your php file.

Related

Struggling with (understanding) PHP Asynchronous Requests

I'm really struggling to understand the way PHP asynchronous requests work. It seems to me that there cannot be any true asynchronous behaviour in PHP because to receive a response from an asynchronous request, you have to delay execution of the script (blocking, essentially) which then defeats the purpose.. right?
What I'm trying to do from a page on my site is:
Initiate AJAX request to (local) controller to begin the remote API
requests
Use a loop of GuzzleHTTP requests to remote API
Upon completion of each request, send the result to a socket.io server which then emits a message back to the listening client (the original page that initiated the AJAX request)
Now, I have this working - with one caveat: the GuzzleHTTP requests are not asynchronous and the remote API is very slow (usually takes around 10 seconds to receive the JSON response) so when there are 10 tasks, my connection to the server is frozen for over a minute. Opening new tabs/windows and trying to access the site results in waiting until the original script run has completed.
This seems to indicate that I misunderstood how HTTP requests work. I thought that each individual browser window (or request) was completely separate as far as the server is concerned but from the result I'm seeing, perhaps this is not exactly the case?
This is why I started looking into asynchronous requests and discovered that they don't really seem all that.. asynchronous.
So what I'm really looking for is help filling the gaps/misunderstandings in my knowledge of:
Why the blocking occurs in the first place (in terms of new, completely separate requests)
Where I might look to implement a solution.

Starting a task to continue after a PHP script finishes

I have a PHP script which is run by AJAX. At the end of the script, the server makes an HTTP request to a different server to log the successful completion of the script. The problem is, this second server sometimes takes a while to respond, and I would like this to happen after the AJAX client finishes its request.
Is there some PHP library or similar which could do this? Is my best bet to log the completion to a file on the first server, then have a cron script making the HTTP requests to the second server based on the contents of the file?
U can use file_get_contents to call a remote server from your PHP, or use the more complex, but more feature rich CURL wrapper library PHP has.

ajax abort is not aborting on the server, only for the client

Apparently I use
var x=ajax.....
if(x){x.abort();}
but this does not cause an abortion inside my php file, which by the way although the option is by default it is set to ignore_user_abort(false)
meaning that if connection were to be lost then the script would not continue execution.
The problem is it appears it keeps on executing code although ajax on js client side aborted.
How to accomplish via js the successful abortion of both, client side and server side php stopping.
That is not the way AJAX works in most cases. Once the request is made to the server, the server starts to fulfill it. Even if PHP was set to stop script execution if the client connection was dropped, in a web server configuration, it does not make such a check until output is actually attempted to be sent to the client. So if you are executing a typical AJAX type of script where you simply have a single output event, a client side abort is not going to have any effect on the server side.
If you need to confirm that something was aborted you have to send another request to ask if your job finished or not. That means that after you call xhr.abort() you have to send a request to something like /abort/jobId to find out whether it was able to abort before finishing processing.
There's no magic way to guarantee that the PHP script will stop immediately after the abort() call.

What happens if a user exits the browser or changes page before an AJAX request is over

I am calling a php script over ajax to do some database maintenance. If the user closes the page, hits back, or clicks a link, will the php script be fully executed? Is there a way to do it?
Maybe if the php script called the exec() method or something similar, which would in turn call a script via the console as such:
$ php /var/www/httpdocs/maintenance.php
?
It's a race condition. PHP will detect at some point (usually upon attempting to do output) that Apache is yelling in its face that the remote user has closed the connection. Whether everything you wanted to do is done at that point depends on how your code's structured.
If you want to ensure that all operations are complete before the script shuts itself down, use ignore_user_abort(TRUE), which keeps PHP running after the connection is severed. It's still subject to the user max_execution_time limits and whatnot, but it will not shut down because you disconnected.
As long as the user agent (browser, etc.) has fully sent the request, the server has all it needs and will complete the request and try to send back a response.
In fact, this sort of "pinging" behavior is often used for "heartbeat"-like processes that keep a service warm or perform periodic maintenance.
Once the web request makes it to your server, it really doesn't matter if the user closes their browser or navigates away. Your server will still respond, but no one will be listening for the response.
Varies on the settings, web server, operating system and so on.
Usually the request will be processed as usual, and the response will just never be read. Occasionally, a write might fail earlier, and the request fails while processing.
Once the ajax call is kicked off, the user is free to do whatever they want. If they close the page they simply won't get the feedback (if any ) from the ajax call that was made.
If the php starts executing then it will continue to execute regardless if the user closes the window or navigates away from the page.
The php script will complete, regardless of browser state. The php is parsed on the server, and that doesn't care about whether the client is still open or not.
If the HTTP request was completed, then yes, the PHP script will be executed fully even if the client's computer is closed.

How long do PHP static variables persist?

How long do PHP static variables persist, i.e. how long does a "PHP run" persist? With say a command line program there is a defined start and end, but in web w/ AJAX I don't know how to define this.
Here are 3 ways I've seen a PHP script started.
User (Requesing a PHP page)
Javacript calling PHP (AJAX)
PHP calling more PHP via a header()
In my actual application I have javascript call a php script via AJAX that script uses the header() to reload the site. This would be consideredt two different runs. Each has their own static variables that do not relate.
PHP variables persist for the lifetime of the script running through the interpreter. In the case of a web request, this is the lifetime of handling the requests. Your three cases are all requests to a server, and thus are handled the same: the static variables survive until the script terminates after handling the request.
The life span of PHP (and its variables) over a request:
Request is sent to server, whether by user, ajax, curl through PHP or what-have-you
Relevant PHP script is executed, whether as a module on your web server, a CGI worker process, or other options
Script is executed, response to the request (if any) is created and sent
(optional) script continues to execute some other job until eventual termination, at which time all its variables die with it.
The "PHP run" is always from start of execution untill the end of the script. So, if you call a PHP script with ajax or a PHP calls another PHP via a header(), each call is a single run. The static variables instantiated earlier do not have a persistant state and will be redefined.
Either static variables or not...if you want to have a persistent state of data throughout those requests you will either have to save it in the session, cookie, database, or in a cache.
It depends on the server setup. Typically, when you make a request, the PHP interpreter is loaded, parses the script, your server spits out the results and the interpreter is destroyed. This happens for each request, regardless of whether it originates from a user browsing or AJAX. What this means is that "static" variables are only valid until the interpreter is destroyed, which again, is at the end of every request. (HTTP is stateless)
What do you mean by "PHP calling more PHP via a header()"? Are you referring to a redirect? In that case, it's a new request. If you meant "PHP calling more PHP via an include", it's typically not a new request (the edge case being you are including a PHP script from a 3rd party.. dangerous and not recommended). With an include, PHP simply loads and executes the file in the same context as the originating script.
The PHP static (that could be considered "global" in a procedural way) doesn't persist in any of your cases.
In each of them a new HTTP request is performed and the Php variables state is lost.
In the command line there is a defined start and end.
There is no difference in PHP running on a server. When a web request is made to the script, the script runs till the end of the script, or until it crashes or has a time-out (and possibly other similar issues).
AJAX doesn't run server side. AJAX is another client side asynchronous call to a server resource. Everything that's done for the first request as far as authentication, validation, input checking, etc has to be done with every subsequent request. The difference in an AJAX response is that the PHP script is likely to return only the content that's requested.
The only time a program will "persist" is if it has been told to keep going. PHP can be told to wait, and perform actions via web sockets, but that seems to be outside the scope of your question.
All three are the same.
In each case, the user's browser is making an http request for the url. The runtime is from the time the server receives the request to the time it is fullfilled.
The PHP scripts stops when you exit, reaches the end of the script or fails.

Categories