I have a PHP file that I want to show a loading text or an image to the visitor, while it is fully loaded.
As far as I know, I should use ob_flush(); to do so.
I tried the following code:
<?php
ob_start();
echo '<div> Loading </div>';
ob_end_flush();
ob_flush();
flush();
ob_start();
ob_clean();
//my php code
//my php code
?>
With this code everything is ok, the loading text appears first of all and then the PHP exception starts. But my problem is that after the PHP execution completes, the loading text is still on the page and it doesn't disappear.
Please help me solve this problem :)
No, this is not what ob_flush() is for. It is not possible at all with a server side language like PHP. You have to use javascript instead.
Here is the roughly simplified and not 100% accurate description what happens when you request a PHP webpage:
Browser sends a request to the server "Hey server, give me page Home"
Server runs the PHP script for page Home
Usually, the PHP script will generate some output. The server will collect this output.
When the script has completed, the server says "OK Browser, here is your Home page", sends the output (the response) to the browser and then closes the connection.
The connection is now closed and the server has already forgotten that the browser has even asked for a page 1 second ago.
The browser will happily display the newly receieved webpage. There is no way to make something happen in the browser now for your PHP script.
That's called the Request Response Pattern and it's still somewhat fundamental to the web.
So how can you get your loading overlay now? When you can accept that the loading overlay doesn't work on the initial page request, but everytime a user klicks a link on your site, you can use following simple approach.
<!DOCTYPE html>
<html>
<head>
<title>Loading overlay test</title>
</head>
<body>
Click me!
<script>
document.addEventListener(
'click',
function() {
if(event.target.matches('a')) {
document.body.innerHTML = "Loading next page ...";
}
},
false
);
</script>
</body>
</html>
If your page loads fast you will probably not see the effect. I kept the example as simple as possible with some plain text instead of a real loading overlay, you can use this as a starting point.
When you absolutely need an overlay for the first page request, things get more complicated. Here is a non-production ready and ajax-less example:
<?php
// Detect 1st page hit
if(empty($_GET['fetch_real_page'])) {
// Loading page - keep as simple(fast) as possible,
// prevent any slow database queries etc.
?>
<!DOCTYPE html>
<html>
<head>
<title>The loading page</title>
</head>
<body>
Loading first page...
<script>
// This will instantly request the "real" page
window.location.replace(window.location.href + '?fetch_real_page=1');
</script>
</body>
</html>
<?php
exit;
// (Does not need to be called explicitely
// when nothing comes after the if-else construct)
} else {
sleep(2);
// Simulates a slow page load,
// do all the heavy database stuff that slows down your page here.
// Then, output the "real" page:
?>
<!DOCTYPE html>
<html>
<head>
<title>The real page</title>
</head>
<body>
Click me!
<script>
// Set up the loading overlay for secondary requests
document.addEventListener(
'click',
function() {
if(event.target.matches('a')) {
document.body.innerHTML = "Loading next page ...";
}
},
false
);
</script>
</body>
</html>
<?php
}
?>
Things to consider:
You need to extend every internal link with fetch_real_page=1
Sooner or later you need to deal with additional $_GET parameters, so you must extend this code, or switch to cookies or the session to check whether the request is a secondary one or not.
The end of the road will be a javascript/ajax-driven single page app but I think this is beyond the scope of your question.
Beware of this unreadable mix of PHP tags and HTML, code like that is frowned upon for good reasons. This is for demonstration only.
Related
I apologize if this seems stupid or redundant, I've search and read related pages with little understanding.
I use this function to call my chat widget to each page. (In case I would like to switch chat server.)
<?PHP include "newchat.php"; ?>
I would like to refresh newchat.php at an interval of 20 minutes. (To prevent chat time out.)
I use this code on newchat.php, which results in the entire main page to refresh. (ie. index.php)
<html>
<head>
<script type="text/JavaScript">
<!--
function timedRefresh(timeoutPeriod) {
setTimeout("location.reload(true);",timeoutPeriod);
}
// -->
</script>
</head>
<body onload="JavaScript:timedRefresh(10000);">
*chat script here*
I think I may need to put script/ajax on each template page, which tells browser to refresh only that element, however I do not understand this code and am not sure if it applies.
Thank you for reading and help you may provide.
Try putting your newchat.php file into a iFrame on your pages instead of directly including it. ie:
<iframe src="newchat.php" id="chatFrame" frameborder="0" width="YOUR-WIDTH" height="YOUR-HEIGHT">
Then you can refresh from with-in the newchat.php file. Or if you want control over it from each page you can use the iframes id to control a refresh from the parent:
document.getElementById('chatFrame').contentDocument.location.reload(true);
I'm new to PHP and this is something that I don't know how to do, even though I have been searching it.
I know that redirecting can be made with Location("some page"). I also read that this works just if there is nothing displayed to user.
What I want to do is:
Display a message to user. echo "message.redirecting...."
Wait for 2 seconds sleep(2);
Then redirect Location("some page");
Any ideas?
Andrew
This is part of an assignment and javascript is not allowed. Only PHP.
You can use a meta refresh, which is just a html meta tag placed inside the <head> of your page. Like this:
<meta http-equiv="refresh" content="2;url=http://newurl.com/">
This will redirect the page to the http://newurl.com after 2 seconds.
Do not do it this way.
It's VERY bad usability.
And there is not much sense in saying "redirecting".
That's legacy of ancient ages of raw HTML sites. No good site using such redirects these days.
Redirect with no messages.
Unfortunately you can't do that. header() calls, such as header('Location: '); rely on http headers, which have to be sent before any output is sent to the client.
I reccomend using a Javascript Redirect if you want a message displayed to the users.
<html>
<head>
<script type="text/javascript">
<!--
function delayer(){
window.location = "../javascriptredirect.php"
}
//-->
</script>
</head>
<body onLoad="setTimeout('delayer()', 5000)">
<h2>Prepare to be redirected!</h2>
<p>This page is a time delay redirect, please update your bookmarks to our new
location!</p>
</body>
</html>
or you can do a php redirect like this:
<?php
header("Location: http://www.example.com/"); /* Redirect browser */
?>
I have some javascripts that I am using in my files. But when we view the source code it shows our javascript as it is. Is there any way with which we can hide our javascript from showing up in the browser using php.
There is a free javascript obfuscator at javascriptobfuscator.com. It will not prevent dedicated people from "stealing" your code, but normal copy&paste will not be easy.
Also see this question: How can I obfuscate (protect) JavaScript? . It contains some very good answers and also explain how this is security through obscurity.
That's how it works, it visible to everyone.
You can obfuscate it, though.
As Javascript is executed inside the browser, on the client's machine, it has to be sent to that client machine.
So, one way or another, the client has to be able to read it. So, no, you cannot prevent your users from seeing the JS code if they want to.
You could obfuscate it, but someone who really want to get to your source will always be able to (event if it's hard)... But the thing is : why would you prevent your users from seeing the JS source code if they want to ?
As a sidenote : with minified/obfuscated JS code, when you'll have a bug, it'll be really harder to track down... (and you really have to keep a no-obfuscated version on your development/testing machine)
I recommend minifying it and that will remove the comments and white spacing from your code. If you don't want the names of the variables visible then you will need to obfuscate it.
I'm not sure if this will work, I may try it sometime. But basically:
<script type="text/javascript" src="MyScript.php"></script>
In the PHP file add some sort of refering to check what page requested it or what the last page was. Then if it was one of your own pages, then echo the JS, if not then don't echo it. It will still be possible to read the JS, but even harder than just viewing source and de-obfuscate it. So you could also obfuscate the code inside the .php file.
no. javascript executes on the client side.
There is another way of hiding the Javascript for the most simple users
Just test here to try finding the javascript behind the textbox...
Yet, the script is still visible for experienced users -see the bottom of this post to understand why-
The idea is to put your javascript functions in a separate ".js" file. When loading your source PHP or HTML page, instead of calling it directly with
<SCRIPT language="JavaScript" SRC="original_file_to_hide.js"></SCRIPT>
, you will include a header php script that will copy the "mysource.js" file to a random "kcdslqkjfldsqkj.js" file, and modify your HTML file to call
<SCRIPT language="JavaScript" SRC="temporary_copy_of_the_file.js"></SCRIPT>
instead. After that, just delete the copy kcdslqkjfldsqkj.js file on your server, and when the user will look for the source code, the browser will link to a vanished file !!!
So this is for the theory, next, there is a small issue to workaround : if the HTML/PHP file is loaded too fast, your script will be vanished from your server before the browser had time to load the script.
Thus, you need
To copy the file to a different random name
To load the file in the source PHP file
To wait a few seconds after your HTML/PHP file is loaded before...
...Deleting the file
Here is the source for the HTML/PHP "test.php" page which is to be displayed to the end-user:
<?php
//javascript source code hiding technique : Philippe PUECH, 2013
//function thanks to Stackoverflow, slightly modified
//http://stackoverflow.com/questions/4356289/php-random-string-generator
function RandomString()
{
$characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
$randstring = '';
for ($i = 0; $i < 10; $i++)
{
$randstring = $randstring.$characters[rand(0, strlen($characters))];
}
return $randstring;
}
//simple header script to create a copy of your "precious" javascript ".js" file
$original_filename="functions.js"; //find a better (complicated) name for your file
$hidden_filename=RandomString().".js"; //temporary filename
copy($original_filename,$hidden_filename);
?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Catch my Javascript if you can !</title>
</head>
<SCRIPT language="JavaScript" SRC="<?php echo($hidden_filename); ?>"></SCRIPT>
<script type="text/javascript">
</script>
<body onLoad="javascript:testfunc();">
This is the page with anything you like !
</body>
</html>
<?php
sleep(1);
//you can comment following line
echo "finished !";
unlink($hidden_filename);
?>
Here is the source for the "functions.js" file which will be hidden to the user.
// JavaScript Document
function testfunc(){
alert("It works...");
}
However, as told in the comment, the developer tools of the browser will keep the script in memory, and make it still visible to the curious users... ;-((
I have a page that does the following:
The browser loads a very simple page with a valid head and body, with only a script/noscript pair as content.
In the body, it has a script (script a) that runs a function onLoad. This function dynamically includes a second script (script b), and runs a function in it when it becomes available.
The second script is a .js file that does various work.
Both scripts are parsed by PHP and use the application/x-javascript content type.
Now, I have this all working just fine, except a couple of JS hiccups. JavaScript isn't one of my strong languages, so I'm hoping these are simple issues and somebody can point me in the right direction.
Problem 1: If I do a simple alert('you are in script b'); in the second script, it works as expected. However, if I do anything else, it works fine, and then the browser keeps indicating that it is loading forever. This is the color tween in firefox, or the spinning thing in IE.
I've tried ending the script in different ways, and nothing seems to help. Any idea how to indicate to the browser that the script is all the way loaded? It's a .js file that is forced to parse through PHP.
Problem 2: The second script doesn't seem to be included at all in either Opera or Google Chrome. Works fine in FF/IE, other than the loading issue. Can anyone see if Im using something that isn't compatible in the loading of the second script?
Thanks!
Update:
Thanks for the answers. I actually have firebug, which is why I know everything is working properly (in FF, at least). I don't actually know that the script isn't working in Opera/Chrome, but nothing happens.
It is quite a bit of code =o) I will copy the actual responses out of firebug and post those, so you can see exactly what the code is. As far as the webserver closing the connection, I was thinking that too, but it seems odd that if I make script b into alert('whatever'); it will alert and then stop loading, but it I do everything exactly identical, but make the script document.write('whatever); it will load forever.
Here are the scripts, updated, copied directly from the net tab of firebug:
Note that discoverfire.net is an internal domain, so you won't be able to load anything from there...
Initial HTML page:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Welcome!</title>
<style>body { font-family:arial; }</style>
<script language="JavaScript" type="text/javascript" src="http://www.discoverfire.net/analytics/l/a.js">
</script>
<script language="JavaScript" type="text/javascript">
document.onload = Start();
function Start(){
TAFKing_version = '1.0';
TAFKing_lkey = '19-8O-KKA8HV';
TAFKing_Lander();
}
</script>
</head>
<body>
<noscript>
Oops! We can't forward you properly because your JavaScript is turned off.<br /><br />
<a href='http://www.discoverfire.net/analytics/l/noscript/19-8O-KKA8HV.html'>Please click here to continue.</a>
<img src='http://www.discoverfire.net/analytics/l/imp/19-8O-KKA8HV.png' border='0' alt='tell a friend' />
</noscript>
</body>
</html>
** Script A (...a.js): http://www.discoverfire.net/analytics/l/a.js **
function TAFKing_Lander(){
version = TAFKing_version;
lkey = TAFKing_lkey;
var scrb = document.createElement('script');
scrb.type = 'text/javascript';
scrb.src = 'http://www.discoverfire.net/analytics/l/b.js?lkey='+lkey+'&version='+version+'&cb=4eohe8e65'
;
document.getElementsByTagName('head')[0].appendChild(scrb);
Interval = setInterval("Waiter()", 10);
return;
}
function Waiter(){
if(window.TAFKing_LanderB) {
clearInterval(Interval);
TAFKing_LanderB();
}
}
Script B (...b.js): http://www.discoverfire.net/analytics/l/b.js?lkey=19-8O-KKA8HV&version=1.0&cb=4eohe8e65
function TAFKing_LanderB(){
document.write("there are just a whole bunch of doc.writes here that build a simple table");
}
I bet it is nothing related with the scripts, but with the webserver. Your description, specially that it affects many browsers, and some of them don't even run the scripts, leads me to believe that the webserver is not closing the connection. Perhaps the webserver is not properly handling HTTP/1.1 Keep-alive requests.
Try using Firebug in Firefox. Install it, enable it for your page, reload the page and check the "Net" tab for what really is keeping the connection open.
This is a lot of code to go through. You should definitely get Firebug to help you diagnose it. The latest version will even show you when/if the onload events occur.
Firebug will also allow you to output message simply by writing console.log('somevar=',var); to test their values. You can even use the console to test value after the page has loaded since you're using the global name space.
Off the top of my head, I would make sure the connection properly closes in php. Also
document.onload = Start();
would assign the result of Start() to onload, not Start which is defined later.
Also window.onload is more compatible/standard.
You may want to save the output of your js files as outputphpA.js and outputphpB.js, directly source those and see if the loading behavior differs. That should help diagnose if it's a php issue.
Is there a way to make sure a (large, 300K) background picture is always displayed first BEFORE any other content is shown on the page?
On the server we have access to PHP.
All the html content is served and parsed before it even starts to fetch the image, so you have a problem before you start.
You could circumvent this by programmatically hiding the content, and then triggering a "show" of it when the image is loaded.
ie:
<html>
<body>
<image here/>
<div id="content" style="display:none;" >
</div>
<script type="psudocode">
when(image.loaded){
$("#content").show();
}
</script>
</body>
</html>
If you have all content inside a container, you can probably come pretty close using this techique. It will also fail gracefully if javascript is disabled/unavailable.
So if you have to do this because of a manager or something, this is the method I would use.
<html><head><!-- head section --></head>
<body>
<div id="container">
<script type="text/javascript">
<!--
document.getElementById('container').style.display = 'none';
-->
</script>
Content goes here
</div>
<script type="text/javascript">
<!--
document.getElementById('container').style.display = 'block';
-->
</script>
</body></html>
If you have very little content, however, it probably won't do much good.
You could of course add a timer on the second javascript block, to delay it for a second or so :P
<html><head>
<script type="text/javascript">
//Hide on load
onload=function(){
document.body.style.display="none";
var imag = new Image();
imag.onload=function(){
var main = document.body;
main.style.backgroundImage="url("+this.src+")";
main.style.display="";
};
imag.src="http://dayton.hq.nasa.gov/IMAGES/MEDIUM/GPN-2000-001935.jpg";
}
</script>
</head>
<body>
YOU CAN' T SEE MEE!!
</body>
</html>
A possible way, if you don't want to rely on JavaScript, is to make a dummy page with only the background image. After a few seconds, it redirects to the real page, and the background will load quickly because it is already in cache.
Not a super attractive solution, if the timing is fixed, I reckon.
Note that 300KB is quite big for a background image. I have seen worse, somebody using a 1MB image: even with a relatively fast connexion, I could see the background load way after the elements of the page.
I think the only way you'll be able to do this is with javascript - Send the user HTML that only contains your background image and some javascript that either waits for a certain amount of time before displaying the rest of the content or uses AJAX to retrieve the rest of the content (essentially the same thing).
You could load the image within the page as a base64 image then it will already be loaded with the page.