I want to send the http status (200 OK) to a calling script BEFORE the rest of the code executes in a php script. For sending the status code, i am using HTTP/1.1 200 OK but it is sending the status AFTER the entire script is finished executing, which makes the calling script to wait. I am not really sure if that is even possible. any help?
Detailed: say i have two scripts, a.php and b.php. a.php is calling b.php and waiting for a http status, if it is 200 then it carries on doing something else. I want the b.php script to be such that, as soon as it is called, it sends back a 200 response and then continues with its own code.
Thanks!
Edit: After reading the comments, i understood that what i wanted to do is a bad idea. However, let me say why i was thinking it and can something like that be done.
a.php would have a web interface where people can upload their images, after the upload is done a.php calls b.php which does some processing using these images. I wanted a.php to continue and not hang/wait for b.php to finish, in case b.php fails, I thought i might be able to "push" a error so that a.php can prompt the user about the failure. Should different threads be used?
PHP can certainly do it, but it's a little bit tricky.
ignore_user_abort(true);
header("Content-Length: 0");
header("Connection: Close");
flush();
session_write_close();
// do something that takes very long
This is the minimal code you need. If you don't have a session you can leave off the last call.
Once you've closed the connection you can't send updates though, so if you want to do something with error reporting you'll have to find another way.
You have functions like flush()
that do what you need but with certain caveats. Read more at: http://php.net/manual/en/function.flush.php.
Since you are calling the PHP script in code, you don't have to worry about the browser issues listed. But if something like mod_gzip is enabled, this won't be possible.
If your a.php wants b.php to run asynchronously, you might consider using cURL POST method to start the script. a.php can set the timeout to be 1 second, and the cURL session will stop. And b.php will keep running while a.php also keeps running.
Hmm, sounds like you would probably be better off using something that allows for socket-based connections. Check out NodeJS. I think PHP may support some form of socket based connection as well. What you are trying to do using "flush" is actually really bad practice. PHP wasn't designed for multiple payloads, and if you are using AJAX you are going to run into a bunch of issues.
a.php is calling b.php and waiting for a http status, if it is 200 then it carries on doing something else
Short answer is that you can't control when the webserver flushes it's buffer. Hence you need to bypass the webserver to invoke b.php. The problem is that if you invoke it via exec / system / etc then b.hpp becomes a child process of a.php - which is a really bad idea if b.php is going to take any length of time to complete.
Given that you need to take a completely different tack to implement a solution to the problem, it's ciriticall important to know why you want it to emit an unconditional 200 status before it does any useful work (when it's most likely to fail while it's doing useful work).
Based on the information you have provided (which is not a great deal) the only reliable way to implement this would be via a mesage queue (and a custom subscriber running in a daemon) - assuming that you can substitute a successful enqueue operation for the resturned status code. But that has it's own complications.
I am thinking of AJAX or XMLRPC but as @Andrew said php is not working like that.. NodeJS is really a good alternative...