?
Solved

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

Posted on 2006-04-26
13
Medium Priority
?
698 Views
Last Modified: 2007-12-19
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.
0
Comment
Question by:jgantes
  • 6
  • 3
  • 2
  • +2
13 Comments
 
LVL 15

Assisted Solution

by:m1tk4
m1tk4 earned 600 total points
ID: 16549233
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
 

Author Comment

by:jgantes
ID: 16550222
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
 
LVL 6

Expert Comment

by:Brian Bush
ID: 16550542
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 29

Accepted Solution

by:
TeRReF earned 800 total points
ID: 16550554
You can put it in the same page if you use something like this:

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

// your other code
0
 
LVL 6

Assisted Solution

by:soapergem
soapergem earned 600 total points
ID: 16550613
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
 
LVL 15

Expert Comment

by:m1tk4
ID: 16552210
>>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
 

Author Comment

by:jgantes
ID: 16555540
Great responses.  Give me a few hours so I can test and I'll get back to everyone.

Thank you.
0
 

Author Comment

by:jgantes
ID: 16559697
Thank you for all the help.  I used flush and it works well!

0
 

Author Comment

by:jgantes
ID: 16560503
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
 
LVL 29

Expert Comment

by:TeRReF
ID: 16565537
Mmm, weird... try this:
ob_start();
print("Please wait...");
ob_flush();
flush();
0
 

Author Comment

by:jgantes
ID: 16565706
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
 

Author Comment

by:jgantes
ID: 16568139
GOOD CALL the OB_START() fixed my issue.

Thanks.
0
 
LVL 29

Expert Comment

by:TeRReF
ID: 16568371
You're welcome. Don't forget to close the question :)
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Developers of all skill levels should learn to use current best practices when developing websites. However many developers, new and old, fall into the trap of using deprecated features because this is what so many tutorials and books tell them to u…
Part of the Global Positioning System A geocode (https://developers.google.com/maps/documentation/geocoding/) is the major subset of a GPS coordinate (http://en.wikipedia.org/wiki/Global_Positioning_System), the other parts being the altitude and t…
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.
Suggested Courses
Course of the Month17 days, 8 hours left to enroll

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question