Jquery Post/AJAX - Does closing window with code affect server script? - php

To preface, I know this isn't a great question and it will be hard to explain.
I have a PHP script that takes 5-10 minutes to run. I don't want the user to have to wait for it. If I "trigger" the script using jquery ajax, and then the user navigates away from that page or closes the browser (and doesn't wait for the response (if any) which will come much later), will the script still execute fully (assuming there are no errors etc)
Thanks!

Once the server receives the AJAX Request along with the data, it would process it as usual, even if you close the page or the window. If you close the browser window before the server receives the AJAX Request, the processing it not going to happen.
Furthermore, if the AJAX Request is returning any kind of data or displaying messages, it is advised that you leave the window open, so that there is some "Listening" page to the Server's Request Response.

In your PHP script you could call the ignore_user_abort(true) function which would cause the script to run regardless of the user closing the page or not.

You could use the command line if you have access to one:
php /loc/to/file.php
This does not have a timeout and might be faster than port:80 (a browser calling an phpfile)
Or call the main phpfile in another file via a php's exec():
<?php
exec("php /loc/to/file.php > /loc/to/result.txt");
?>
You might want to use shell_exec()
The dir of results.txt and the file itself need to be writable.
The 'greater than' sign writes the output of the phpfile to result.txt. If the php would echo 123, that would be the contents of result.txt
5 to 10 minutes is a very long time, you might want to check your code for improvements. If you are using a database, add indice (an index) on columns u use allot, that ccan save huge amounts of tim

Related

Long PHP scripts and echos/prints

I have some PHP scripts that can be called either from the command line or as a webpage (where the arguments are passed from other web pages using $GET or $POST).
They can take a while to execute, let’s say 5 minutes.
The scripts include some “echo” & “print” calls which allow me to know what is happening during the execution in real time.
The problem is that, in webpage mode, those echo calls don’t print anything in the browser till the end of the script execution. Or sometimes, half the echos appears after 2 minutes and the rest at the end.
Is there a simple way to make my print()/echo() calls appear in real time when my script are called in “webpage mode”?
Thanks in advance.
flush() may or may not work depending on the browser and size of the output (see: PHP Flush() not working in Chrome)
Apache can also buffer output if mod_gzip is enabled.
Your best bet is to log into a db/session/fs and have JS on client side polling for updates.
Use ob_flush() to force output to be sent to the browser before script execution completes.
I assume you are not using output buffering as your script outputs fine on consolde. Therefore use flush() to explicitely tell PHP it should send output to the browser.
I would suggest a flush every xxx outputs instead of flushing after every echo or print if they appear in short intervals.

Javascript not reflecting changes to a file

So, I'm a bit confused here.
I'm slowly progressing into ajax or HTML5 SSE, because I have list that, in the long run, I want to update without the user having to refresh. But, baby steps here, I'm starting with a simple function that should tell me when the file the list is reading from here, has changed, from another computer plugging in an entry.
CODE:
<script type='text/javascript'>
function CheckForChange(){
alert("<?echo (count($listArray)) . ' and ' . count(file($filename_noformat))?>");
}
setInterval("CheckForChange()", 7000);
</script>
listArray is the PHP variable that keeps the list seen on the page when the page refreshes, read line by line from a text file (I'm working on moving to a database, later)
Since PHP variables can only execute when the page is loaded, the PHP would only reflect what was in the text file when the PHP executed.
But with Javascript, and the setInterval function, shouldn't it be able to execute the PHP to check what's in the text file at the time that function is executed (every 7 seconds)? Because it's not, and I don't understand why not.
I try plugging in a 4th post to the list on my phone, and the phone's alert changes to 4 and 4, but the computer still says 3 and 3. I want it to say 3 and 4.
Thanks
setInterval() executes local javascript in your page, not server-based PHP. If you want it to send something to your server without reloading the page, you would have to use an ajax call to actually send something to the server which could cause some PHP to execute.
Hint - look at View/Source in your browser and see what is actually in your page. There's no PHP in your page. The PHP runs on the server once when the page is created.
No.
The PHP runs on the server and outputs some text.
The server sends that text to the client (the browser).
The browser then interprets that text as HTML and JavaScript.
The PHP runs only once. The JavaScript function it generates then is run repeatedly, but from JavaScript's perspective, that function has a string literal in it, not executable server side code.
If you want to run PHP then you have to issue a new HTTP request to the server. This requires either reloading the page or using Ajax.

How Ajax enables a Javascript string to be passed to php

I've been learning Ajax and now I'm wondering how it allows a string from Javascript to be passed to php.
It was said before that the problem with passing Javascript to PHP is that the PHP code gets run first, and then the Javascript gets run. So when Javascript generates a string it's already too late.
Does this mean that Ajax allows PHP code to be run after Javascript?
I think this is what they're getting at:
Before Ajax -- specifically, before XMLHttpRequest came along -- a single web page was served as a single page load. If it was a PHP-generated page incorporating Javascript, the browser would request the page, PHP would generate the page (including Javascript code, includes, fragments of script on the page, etc.), would send the page to the browser, and the browser would display it. So, the PHP happened up-front. Until the next page load -- when the entire page was refreshed from scratch -- PHP wasn't involved again.
After the advent of XMLHttpRequest, which helped put the "X" in "AJAX", as it was back then, you had another option. Once the page was loaded, your Javascript could make requests "behind the scenes" of the page, to request more information from the server, without reloading the page. In effect, the loaded page could cause more PHP to be run on the server, and display the results.
So, if you're considering a single page load from a PHP-based website, that is (sort of) what Ajax means; without it, you get a single PHP page-build that's delivered and then your Javascript has to run on that result alone. With Ajax, you can make further requests to your server and throw the results out onto the existing page without a full page load.
The php interpreter sitting on the server is basically interprets whatever php script into (usually) HTML page.
That's why you can never "pass" javascript variable into php as to the interpreter, your javascript is just yet another string, without any special meaning. Your javascript is run by your browser and doesn't even aware that it was being produced by PHP.
I believe that's what it means by "too late".
You should know, that Javascript is always (except Node.js) Client-Side.
PHP is a Server-Side language.
You can't pass Javascript variables to PHP - at least not at the Pageload.
What you can do is doing a AJAX-Request after the Page is laoded to send something to PHP.
With the Response of that call you can replace some other things on the current requested Page.
No it does not mean that "Ajax allows PHP code to be run after Javascript". AJAX is a new request to the server and it allows you to manipulate with the server's response. You can observe this by coping the url to which AJAX request is being made and pasting it into the browser.
So basically when you open a web site with the browser, you send a request and any AJAX call is also a request, but done in a background, so you cannot see it directly. You can use for example firebug or other developer's tool to see what happens behind the scenes. It has nothing to do with the scripts executions orders.

can i see what data is loaded while an ajax request is in progress?

if i have something like this in php
$foo=0;
while($foo<20){
echo "hello";
usleep(1000000);
$foo=$foo+1;
}
and i make an ajax request to that php file, can i do anything with the data while the request is in progress?
i mean, the script echos hello every second and i saw that the request only shows what data it has when the whole loop is finished, so isnt there a way i can access each hello when its echoed out?
Look for firebug extension of Firefox.
There are a few reasons why you can'y see it.
The content coming from the AJAX request is processed by the server like any other http/php request.
What is happening is the data is being cached by the php buffer, then when its done its flushing it to the output. Which apache then delivers to you.
There is so little data that there is no need to flush this buffer before the processes is done. So you are only seeing the final result.
If you had some much data outputted that it cause the output to be flushed before hand then you may get it.
The other problem is going to be you ajax request handler. I'm pretty sure the onComplete (or similar) method that you (and everyone else) is using will only be called when the output from the server request is finishing and your browser has the full data.
It may be possible to use a different event or perhaps write the ajax code your self (with out using stuff like jQuery) but i'm not even sure if that would solve your problem; as this might also be something to do the with x http request implementation.
May i ask what your are trying to do this for? there may be an easier solution for your actually problem *i'm assuming this isn't the code your actually are using on your site).
Dan
If you execute the flush(); command in PHP you will send content. If you're compressing at the server level you may need to pad output to fill up a packet to make it send.
flush();
Here's an example: http://example.preinheimer.com/flush.php
The correct answer is you CAN see the content while it's being returned.
The other answers were partially correct in mentioning that the PHP output buffer will keep the output "bottled up"... but the output buffer can be disabled.
Once you disable the output buffer you need to show the JQuery response before the request completes - you do this by updating the browser periodically while the connection to the server is still active. This concept is called "Comet" or "Long Polling".
See these questions:
Comet and jQuery
How do I implement basic "Long Polling"?
Comet In PHP

PHP $_SESSION not available until the page is reloaded. Why?

I'm creating a graph that does some database queries then builds the graph using GD functions then also puts the info from the database into an array that is stored in $_SESSION['my_data']. This graph is displayed on the web page using img tags.
<img src="my_graph.php?time=$time">
<?
print_r($_SESSION['my_data']);
?>
The problem is when I print_r() the array from the session variable it doesn't print the current graphs data; it prints the data that was in the graph last time the page was loaded. It's acting like a cookie.
I have tried putting session_write_close() immediately after I store the array in the session because I thought $_SESSION might have been locked until my_graph.php finished loading the image. That did not work.
I also tried putting sleep(10) before I print the array and that did not work.
Why this would happen?
I suppose, when your web server executes PHP code, which draws our page, it already has $_SESSION array initialized. And this array is not updated in current script runtime. When browser finds image tag, it makes another request to web server, which executes image generation script, which updates $_SESSION array in another runtime.
You may:
either make all calculations in your web page generation code
or reload page after image generation script completes calculations and sets all necessary data in $_SESSION array
If you are setting $_SESSION['my_data'] in mygraph.php, you will never see your $_SESSIONchange until your browser requests mygraph.php. This will never occur until the output is flushed to the browser (which will be AFTER you've already print_r() the $_SESSION).
You may be able to try flush() and hope the browser requests the image before you are done executing, I've never tried that (not sure if it will work). Though, sometimes you have to pad output with whitespace until it is about 2k (if I'm not mistaken). I wouldn't recommend this, though.
Another solution would be to request the page you have your code in above in the src. So if your code above is in test.php you could put <img src="test.php?img=true&time=$time">. Then if you get $_GET['img'], display an image, otherwise execute some code. Does that make sense?
Sequence of events:
Browser requests the main web page.
PHP runs the main page and sends the contents to the browser.
Browser receives the page.
Browser looks at the page and sends requests to load the graphics, etc.
PHP runs graph.php and sends the graphic to the browser.
Browser inserts the graphic into the page.
The important thing to note is that the whole of point 2 occurs before any of point 5 happens. This means that anything that graph.php does with $_SESSION will not be visible to the code in the main page, leading to the effect you're seeing.
This is the nature of a web page: the graphic files are separate from the main PHP program.
You cannot get around this using a separate graphic file the way you're doing it.
There is one way I can think of achieving it, but it would be a complete rewrite (it's up to you to decide whether it's worth it!)
It is possible to create a graph using Javascript. If you generate the javascript code to do this in the main page, you could then set $_SESSION during the graph generation code, and it would be available later in the program.
If you do decide to do this, you should look into the gRaphael library to help you out.
Hope that helps.

Categories