How to make a "Please Wait..." page while php does something in the background...?

I'm trying to accomplish what I think would be a simple task.

I have a PHP page that runs through quite a few queries and takes a bit to process (20 seconds).  I want a page to come up that says "Please wait..." and then at the end of the other PHP that's running it would forward it along to the results page.

I'll use ORBITZ as an example.  You enter your data, click SEARCH, it takes a bit.  While you're waiting there are ads and a "Searching..." screen.  The results are displayed only once it's done processing.

I've tried frames, Header(), Include(), Meta tag refresh etc.  You can't put it in the PHP page that does the processing because it won't display anything until PHP is done!  (I am on a windows machine as my development machine using PHP 4 and Apache 1.3.x and MySql 4.1).

I've read about using ob_flush and other similar methods, but is that the only option? If so, any examples?

Any ideas?

Thanks.
jgantesAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

m1tk4Commented:
http://www.experts-exchange.com/Web/Web_Languages/PHP/Q_21828870.html

instead of clearing the <div> you can set location.url='something' in javascript to jump to other page.
0
jgantesAuthor Commented:
How will that work?  PHP dumps everything after it is done processing, so it wouldn't echo that right away...  I'm not sure what you're getting at.

I know I can use /usr/bin/php etc and do an EXEC() but I'd prefer to explore other options first.
0
Brian BushSolutions ArchitectCommented:
A trick I've used in the past is to place an animated GIF in the background.
This is basically how you do it...

Create a GIF that says something like "Loading..." I animated the ellipsis to show
that we aren't locked up.

Add an IFRAME to your page that will load the PHP page:
<IFRAME CLASS="LOADING" SRC="loadingpage.php" FRAMEBORDER="0">

Add a CSS tag to put the GIF in the background:
IFRAME.LOADING {
    background-image: url(loading.gif);
    background-repeat: no-repeat;
}

Now, the image will load and start animating until the PHP page is rendered over
the top of it.

--brian
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

TeRReFCommented:
You can put it in the same page if you use something like this:

print("Please wait...");
ob_flush();
flush();

// your other code
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
soapergemCommented:
What they're getting at is all correct. Using the flush() command will probably do it for you. From the PHP manual:
"This effectively tries to push all the output SO FAR to the user's browser." [emphasis added]

However, this may leave you page only "partially loaded" for 20 seconds since it wouldn't have loaded the lower half of the page. The immediate solution I thought of was: use AJAX. Used properly, this would load the entire page very quickly (minus the queries), display a "loading" message, and then load the query information. So the rest of my answer is dedicated to explaining how to do this.

What is now one page that is slow loading you could break up into two pages (three, if you count the JavaScript file--if you use one separately). Here's what to do.

1) Create the main page that the user will browse to. Think of this as a container page. Let it echo out all the page styles and images and everything else unique about your site, but do not make this page run any of the slow queries. Also, include a <div> element right where you want the output to appear. Define the <div> element to initially be set to a "Loading" message. Something like this:

<div id="main_box"><p>Please wait while the data is loading...</p></div>

And MAKE SURE it has an id-attribute, or at least some other way to identify it in your JavaScript.

2) Create a secondary page that users would not browse to. This page will execute ALL of the queries, and output the data exactly how you would like it to be output. But only include the styling that is immediately necessary. Do not include things like <html>, <title>, and all that extra info, as this information is literally going to be dumped right into the <div> we created on page one. If you want the queries to behave differently depending on certain variables, then you may pass variables to this file as such:

file_two.php?var1=somevalue&var2=5

Inside the PHP code of file_two.php, you would access these variables using this:
$_REQUEST['var1'] and $_REQUEST['var2']

Thus, in the AJAX code you're about to write, you could call a URL like "file_two.php?variable=88" to change the behavior of your code.

3) Use AJAX functions to grab the content from file_two.php and drop it into the <div> we created in file_one.php. Remember, the initial content of this <div> was a "loading" message, so that message will stay there until file_two.php is done processing--at which point this new query data will be dynamically placed into the <div>.

But you ask, "I've never used AJAX before? What functions do I use?" Check out "Rasmus' 30-second AJAX tutorial":
http://rajshekhar.net/blog/archives/85-Rasmus-30-second-AJAX-Tutorial.html

He defines three functions there, and one variable:
function createRequestObject();
function sndReq(action);
function handleResponse();
var http = createRequestObject();

You can safely leave the createRequestObject() function and the http variable intact without any changes. But you'd have to tweak the other two functions to your liking. You could change the sndReq() function to be something like this:

function sndReq(variable1, variable2) {
    http.open('get', 'file_two.php?variable1='+variable1+'&variable2='+variable2);
    http.onreadystatechange = handleResponse;
    http.send(null);
}

In this case, we are accessing file_two.php (the file that executes the queries) and adding two variables. You could add more, less, or none. If you've done any coding, it should be fairly obvious how you'd modify that, but ask if you get confused. You could then change the handleResponse() function to be something like this:

function handleResponse() {
    if(http.readyState == 4){
        var response = http.responseText;
        document.getElementById('main_box').innerHTML = response;
    }
}

That would literally take the data received from file_two.php and place it in <div id="main_box">, and it would do so only after it has loaded all the data. (So your loading message would stay up until it was finished loading.)

You could save these three functions in a separate file, call it ajax.js or something like that, and include that in the <head> section of your document. Then, you would include some further JavaScript just below that include, something like this:

<script type="text/javascript">
/* <![CDATA[ */
var http = createRequestObject();
document.onload = sndReq(variable1, variable2);
/* ]]> */
</script>

That would tell it to send a request to page_two.php as soon as the page loads--which should happen rather quickly because it wouldn't have to do any queries directly any longer. So that's a long-winded three-step answer, but I hope it helps you.
0
m1tk4Commented:
>>How will that work?  PHP dumps everything after it is done processing, so it wouldn't echo that right away...

that's why flush() is there.
0
jgantesAuthor Commented:
Great responses.  Give me a few hours so I can test and I'll get back to everyone.

Thank you.
0
jgantesAuthor Commented:
Thank you for all the help.  I used flush and it works well!

0
jgantesAuthor Commented:
The BELOW WORKS WELL but not for IE, only Mozilla. Do I need "fille" the buffer to a certain point?

print("Please wait...");
ob_flush();
flush();

// your other code
0
TeRReFCommented:
Mmm, weird... try this:
ob_start();
print("Please wait...");
ob_flush();
flush();
0
jgantesAuthor Commented:
I read that IE has a different buffer size that needs to be filled -- could that be true?  I'll tryt he OB_START(); later tonight -- hopefully that solves the problem.

If I do need to fill the buffer, any information on the buffer differences between browsers?
0
jgantesAuthor Commented:
GOOD CALL the OB_START() fixed my issue.

Thanks.
0
TeRReFCommented:
You're welcome. Don't forget to close the question :)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.