11
I have a web application made in PHP, and I wanted to force that whenever I deploy a new version of the application the client is "obliged" to update everything that has changed, such as images, CSS, JS, etc.
How can I do that?
11
I have a web application made in PHP, and I wanted to force that whenever I deploy a new version of the application the client is "obliged" to update everything that has changed, such as images, CSS, JS, etc.
How can I do that?
3
The best way to do this is to use a single parameter in the link that forces you to update your scripts. Example, within the tag head
of your page load the scripts this way:
<script src="script.js?v=<?php echo $version; ?>"></script>
<link href="style.css?v=<?php echo $version; ?>" rel="stylesheet">
Being $version
some string that can be unique depending on each deploy. I usually put the version of the last deploy via Git.
3
In a remote time, I even created a library to manage my scripts and style sheets added to the site.
The main point that made me want to create the library was to have a parameter that I defined in one place that would affect all scripts, images and style sheets I had on my site.
My goal is not to advertise the library here (because I think nowadays I would try to solve it in other ways), but thinking about the case where you have a site with your scripts, images and style sheets, without using modern tools like gulp
, webpack
and the like.
I think you could create a function that you would normally receive as a parameter the name of your Asset. And within that function, he would mount the name for his asset
based on some flag, which would force an update on all your customers.
Sort of like this:
somewhere you define:
define('APP_VERSION', '1.0.0');
You create a small function.
function asset($url) {
return sprintf('%s?version=%s', $url, APP_VERSION);
}
Then, instead of declaring your scripts and images like this:
<img src="/img/futebol.jpg">
<script src="/js/app.js">
You would declare so:
<img src="<?= asset('/img/futebol.jpg') ?>">
<script src="<?= asset('/js/app.js') ?>"></script>
This would make the above generated url:
/img/futebol.jpg?version=1.0.0
/js/app.js?version=1.0.0
Then, if you were to publish a new version in the system, you would just change your constant APP_VERSION
.
define('APP_VERSION', '1.0.1')
This would make your Assets have one ?version=1.0.1
added, thus forcing the client’s browser to pick up new server information.
Advantages of the above method:
Disadvantages:
?version=VERSÃO
different.src
or href
from your Asset directlyThe second technique I had thought of aims to upgrade each Asset individually. But, to do this, it is necessary to know the physical path from Asset, through PHP.
The idea is the same as the above function, with a small modification:
function asset($path)
{
// exemplo : 'c:\window\xampp\htdocs\project\assets/img/futebol.jpg'
$fullpath = __DIR__ . '/assets/' . $path;
return sprintf('%s?last_modified=%d', $path, filemtime($fullpath));
}
In the above case, the function filemtime
is responsible for reading a file on disk and informing, through a unixtimestamp, the last modification date.
In doing so, you would be generating something like this:
/img/futebol.png?last_modified=1535132483
/js/app.js?last_modified=1535632483
Perks
Disadvantages:
filemtime
. Some minimalist people would like to avoid so many calls to that function.But still, it is possible to get around the problem of option 1, described in the disadvantages of the second method. Just check if the file exists, to apply the modification date check. If it does not exist, use option 1 shown!
Example:
define('APP_VERSION', '1.0.1');
function asset($path)
{
$fullpath = __DIR__ . '/assets/' . $path;
// Se existir, coloca a data de modificação
if (file_exists($fullpath)) {
return sprintf('%s?last_modified=%d', $path, filemtime($fullpath));
}
return sprintf('%s?version=%d', $path, APP_VERSION);
}
Comment there, I was wondering if I could use #
instead of ?
. It would work??
Dude, awesome! It would only change one thing, the APP_VERSION
could come from a static file, and in case I would recommend a types of Assets have different versions, but everything else including filemtime I think solves a lot.
Browser other questions tagged php deploy updating
You are not signed in. Login or sign up in order to post.
Asks the user to press CTRL+SHIFT+R!
– Wallace Maxters
Use a parameter as a version with a
timestamp
. Ex:https://www.example.com/images/icons.png?v=1519330900
– Valdeir Psr
I usually do what Valdeir said, but I’m working on a change that will warn clients connected via socket that the site has changed and force Reload
– Karl Zillner
Maybe configure the underlying web server, e.g. using the Apache mod_expires module
– epx
You can browse your Assets (CSS, JS, etc.) using tools such as webpack. Tools like this, allow among other things to add a version number at the end of the original file name as Valdeir Psr said. So the browser will ignore the previously versioned Asset cache and load the newer one.
– Jhonny Freire
Objective question: Are you using any tools to manage Assets? Is it feasible to use? Or want to do this in a project where you’re using the Assets urls directly?
– Wallace Maxters
The best is to change the name of the Assets. Creating a version in querystring only changes the mess. You can change one
main.css?v=125
formain.css?v=127
and suddenly forgot to climb the realmain.css
version 127 - just shot in the foot, because when you climb the real 127, you’ll have to change the version again, because what’s curly like v=127 is 125. If you change the file name, be sure not to confuse either the development or the deploy.– Bacco
"Ah, but if I change the name I’ll have to go through the sources". But it’s better to go through the sources than pretend to solve them. Anyway, you can use a centralized variety and config of names, so in the sources you use link rel="" src="$config_cssmain" and exchange $config_cssmain in a centralized or manifest file, so you have a little more predictability (and ease of giving an emergency rollback only by changing the config if any Asset has problem deploying)
– Bacco
@Bacco but this brings me a problem, that not being serious is boring. In terms of version repository, you will always be creating a new file and never changing the previous one.
– Jorge B.
@Wallacemaxters I’m not using any tool. It might be feasible to use if it doesn’t involve a lot of time/work.
– Jorge B.
@Jorgeb. Anyway, a deploy system is supposed to be able to remove obsolete things, isn’t it? There are many situations where files become unnecessary when updating a framework or even a stylesheet.
– Bacco
@Right Bacco. That’s no problem. The only "problem" is no record of changes in the repository.
– Jorge B.