My site is designed to be a funny picture site, when the user hits the random button a PHP code on the same page generates a new random picture, this is how it is supposed to work. I however have to hit the F5 button to get a new image.
I was reading on another question that people use a get date and get time query string generated at the end of the link to avoid browser caching, I however can not figure it out for the life of me.
I am not very good with php so please speak as if I only know the basic webpage structure. Thank you!
What you are describing is called a cache breaker and is usually a random string or a timestamp appended to the url. When you are referencing your image, prepend it like this:
echo get_random_image_url() . '?' . time();
This will result in an url looking like this:
http://your.server.com/random.jpg?1355862360
Note: get_random_image_url is just an example, but i'm sure you get the idea.
This thread may be of interest: How to force a web browser NOT to cache images.
i think using headers is better than the url trick
<?php
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
?>
http://php.net/manual/en/function.header.php
It is very easy to be solved: for example,
Check the following two links:
http://cdn.arstechnica.net/wp-content/uploads/2012/10/06_Place_20773_1_Mis.jpg
http://cdn.arstechnica.net/wp-content/uploads/2012/10/06_Place_20773_1_Mis.jpg?randomValue
Both of the two links will be open the same image.
This is your solution! You have to add at the end of your image file name a random value:
image.png?<?php echo someRandom();?>
This community or Google for a way to write a function that gemnerates random values.
Also there is solution using javascript, suupose the following
<img id="funny" src="scripts/php_rand_image.php" />
Get another image
<script>
function changeImage(ob){
image = document.getElementById(ob)
d = new Date();
image.src = image.src+'?'+d.getTime();
}
</script>
Related
I'm using Minify (https://code.google.com/p/minify/) to compress and combine ~30 css files and ~10 javascript files. I've created a group configuration for those files, which is basically an array with the filenames.
Works like a charm, except when one of the scripts is modified: browser cache is not timely update. I used to get a last modified timestamp for each file (using filemtime) to overrule browser caching:
$time = '?' . filemtime( $filename );
$output = '<link type="text/css" rel="stylesheet" href="'.$file_path.'?'.$time.'" />';
I could loop through all 40 files to get the latest timestamp, but that is a very ugly solution. Another way would be e.g. to have a crobjob check it and write the timestamp to a file, which I can then include.
Any other ways before I'm inventing the wheel again?
can you not just add:
src="path/to/file.css?v=<?php date(dmy); ?>"
Just get the modification time of the $file_path...? Personally, I have a much more reasonable number of files (two or three) and each one is individually cached with its mtime. Works beautifully.
I can suggest you a way that you need to define a rewrite rule and implement a handler for static file load. Let say it is assethandler.php, and your rewrite rule;
RewriteRule ^nocache/(.*?)$ assethandler.php?f=$1 [QSA,L]
And in php you can use Cache-Control and Expires for getting always latest file;
header("Cache-Control: no-cache, must-revalidate");
header("Expires: Mon, 01 Jul 1990 05:00:00 GMT"); // past date
readfile('path_to_static_files/' . $_GET['f']);
and your static file requests will be like;
<script src="nocache/your.js"/>
Simply, when you make a request to nocache/filename this will be handled as assethandler.php?f=filename and in this handler, cache always disabled and file content served as latest content
I have a php script acting as a random image generator. The script queries the database for the user's images, and returns the path to one, at random. Here is the portion of the code responsible for returning the image, once the path has been chosen.
header('Content-Transfer-Encoding: binary');
header('Content-Type: image/jpeg');
header('Content-Length: ' . filesize($path));
echo file_get_contents($path);
I am calling it from the client like so
image.src = "/database/getRandomImage.php";
Every time I refresh the page I get a new image at random. However, if I call getRandomImage.php multiple times for side by side images, they will all be the same image. If I add a random property to the call like so
image.src = "/database/getRandomImage.php?path=" + Math.random() * 100;
The pictures become random. I take this to mean that the browser is caching them based on the random property I passed. The problem is this property has nothing to do with the actual image. Two different images might get cached as the same image, and the same image might not be retrieved from the cache. Is there any way for getRandomImage.php to inform the browser about the picture it is sending back?
Why not have getRandomImage be a PHP function, which returns a path to the image. You can render the page out with the random image paths already filled in.
<img src="<? echo getRandomImage() ?>">
Then you can actually serve your images with real cache headers, and your bandwidth wont be getting hammered so hard.
Do this on the server side while the page is rendering, not after. Doing it after is more work and, as you are finding out, is more complicated too.
The caching has nothing to do with the PHP script; it happens at the browser.
Try adding this to the script, to try and force the browser to not cache it (from PHP website):
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
Just make randomImage.php redirect to a seeded version if it isn't present.
if (!isset($_REQUEST['seed']))
{
header("Location: randomImage.php?seed="+rand());
exit;
}
Feel free to make the randomizer more random.
Browsers expect that the same will always represent the same image. And I think that even headers that force no caching at all wont even stop the browser from reusing the image on the same page. So a image source that is different each time you call it is pretty counter intuitive.
Cache busting is probably your best bet. That means like you random hack there, although there is ways to do it better. For instance, appending an increasing integer to the current time. This way you never duplicate urls.
var count = 0;
var now = new Date().getTime();
imgs[0].src = "/database/getRandomImage.php?" + (count++) + now;
imgs[1].src = "/database/getRandomImage.php?" + (count++) + now;
imgs[2].src = "/database/getRandomImage.php?" + (count++) + now;
But really, you may want to rethink your strategy here, because it sounds a little fishy.
I've coded an option called 'devmode' in my web app, which basically means 'no caching'. The app normally outputs an automatically minified (and aggregated) version of the Javascript and CSS, but the devmode option overrides this.
However, we still have the browser cache. So, without further ado, how can I disable caching of ALL components on a page if a certain PHP boolean is true?
Cheers
Edit: might interest you to know that I'm running Apache, and one idea I had was to force .js and .css to be parsed as PHP (which is straightforward), and somehow 'inject' a little piece of PHP code at the start of each.
A "quick and dirty" approach for debugging/developing, you could call all components in your HTML with a random (or time-based) query-string. For instance:
<img src="logo.png?uniqecall=20111026035500" />
, which would look like this in your PHP code:
print '<img src="logo.png?uniqecall=' . date("YmdHis") . '" />';
etc...
.htaccess
RewriteRule ^no-cache/(.*?)$ no-cache.php?file=$1 [QSA,L]
no-cache.php
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
readfile('static/'.$_GET['file']);
Assuming you won't hack yourself :)
i am using Google Maps to draw some polylines with markers. Everything is working fine. I am facing problem with Cache. Whenever i do a change and see the Graph it does not reflect the change first time, I have to refresh the page 2 times to see the new change.
To avoid this i am using this at the top of the page :
<?PHP
header("Cache-Control: no-cache, must-revalidate");
header("Expires: Sat, 28 Jul 2007 05:00:00 GMT");
?>
However it is not working as i have refresh the page almost 2 times.
Can anyone suggest me any alternative way to do the same.
Thanks
-Zack
How about sticking this at the top of your script? It'll change the URL of the script each time you access the script. This should prevent browser caching...
if (!isset($_GET['time'])) {
// url of current page, with an added timestamp
$host = $_SERVER['HTTP_HOST'];
$page = $_SERVER['PHP_SELF'];
$url = "http://$host$page?time=".time();
// redirect back to this same page, but changing the URL
// to include the current unix timestamp
header('Location: '.$url);
exit;
}
I am trying to build an application in which i have to stream the media files (audio and video) to the browser. I am reading the file through php and send the data to browser. I am using the following code.
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header("Content-Type: {$file->getMimetype()}");
header("Content-Disposition: inline; filename=".$filename.";");
header("Content-Length: ".strlen($file_content));
echo $file_content;
Every thing is working fine, except when i try to forward the video or audio, (I mean suppose current play location is 0:15 and it directly go to 1:25), media stops and when i press the play button again, it starts from the beginning.
I think the problem is with the buffering, but can't figure it out. Am i doing something wrong in header or something else is required.
Thanks.
I think you need to implement the Range header, so that the client can skip to a specific position in the file. You can probably find out what goes wrong by sniffing the request the player sends.
What you want is called "Content-Range requests"
Have a look here Resumable downloads when using PHP to send the file?
I came across this recently which may help you:
http://www.jasny.net/articles/how-i-php-x-sendfile/
Rather than passing the whole file through PHP (which eats up memory), you can use x-sendfile. This is an Apache module which allows you to run a PHP program, but pass control back to the web server to handle the actual file download once your code has done what it needs to do (authentication, etc).
It means that your PHP code doesn't have to worry about how the file is served; let the web server do what it's designed for.
Hope that helps.
Here is a good tutorial for it, you only want the PHP section but still:
http://www.devshed.com/c/a/PHP/Video-Streaming-PHP-Script-Tutorial/3/