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.
Related
I have a PHP file that takes a while to run, it has several parts to it, Is there a way to send a command back to javascript after part of the PHP file has been completed?
PHP runs in server side and javascript in client side.
First PHP runs in server and once it is completed it sends output to client (browser)
You can use AJAX for your requirement
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.
I'm sending an HTTP POST request from my C++ app to a PHP script on a server. Using HttpOpenRequest/HttpSendRequest/etc. Currently it waits for the PHP script to finish executing before HttpSendRequest returns. Is there anyway to change this functionality?
I'm sending the data just before my C++ application closes, so I don't want it to sit there for 10+ seconds waiting for the PHP script to finish executing. I just want it to send the data, then close the app.
One thing I was thinking was to have the PHP script spawn another PHP script in a different process using the exec command, so the first script would return straight away. However, I'm sending a lot of data with my HTTP POST request, so would need it pass this data to the spawned process.
Ideally I just want a flag to set to tell HttpSendRequest not to wait. I couldn't see anything obvious in the docs, but may have missed something.
You can call InternetOpen with the INTERNET_FLAG_ASYNC and have your callback do nothing of consequence.
Here's some example code to get you started:
http://www.codeproject.com/KB/IP/asyncwininet.aspx
Then (as rik suggests), call ignore_user_abort(true); at the top of your PHP script to ensure it executes fully.
ignore_user_abort
You may want to ignore_user_abort() in your PHP script. Then you can close the connection from your C client after the data is sent and PHP will continue to do whatever it's supposed to do.
I was wondering about the lifespan of a PHP script when called via Ajax. Assume that there is a long-running (i.e. 30 seconds) PHP script on a server and that page is loaded via Ajax. Before the script completes, the user closes the browser. Does the script continue running to completion, is it terminated, or is this a function of the server itself (I'm running Apache fwiw). Thanks for any help.
This may be of interest: ignore_user_abort()
ignore_user_abort — Set whether a client disconnect should abort script execution
However note
PHP will not detect that the user has aborted the connection until an attempt is made to send information to the client.
The script will continue running. Closing the browser on the client does not notify the server to stop processing the request.
If you have a large time consuming script, then I would suggest splitting it up into chunks. Much better that way
The app is downloading a file (plist) which is generated by the server. The server takes a loooong time to generate the file, so I would like to be able to show progress (probably view UIProgressView, but that's not important).
Since the file I'm downloading hasn't been created yet at the beginning of the request, we don't know the expectedContentLength. However, I have the means to provide progress updates from the [PHP] script itself. I'm using ob_flush() for each line in the file to do this, which works just fine in a browser.
But when I make the request from the app, I'm only getting a call from connection:didReceiveData: after the script has finished executing, so that's not of much use.
So my question boils down to this:
How can I tap into the progress of such a php script from my app?
I wouldn't mind sending 2 requests to the server, the first that generates the file and provides updates while doing so, and then another to download the actual file.
Since none of my NSUrlConnection delegate methods are being called until the request completes, what does my script need to do to trigger these methods?
Your problem is most likely on the server. If the server is sending data as it is processed and that processing takes a significant amount of time, you should probably get more than one notification of connection:didReceiveData:.
There is some discussion that might be relevant in the PHP manual.
http://php.net/manual/en/function.ob-flush.php
I would verify using a packet analyzer that the server is actually sending data incrementally as you expect.