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 would be obliged to update everything that had changed, such as images, CSS, JS, etc.
p>How can I do this?
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 would be obliged to update everything that had changed, such as images, CSS, JS, etc.
p>How can I do this?
In a remote time, I even created a library to be able to manage my scripts and style sheets added to the site.
/ p>The main point that made me want to create the library was to have a parameter that I would define in one place and that would affect all the scripts, images and style sheets I had on my site.
My goal is not to advertise the library here (even because I think I would try to solve it in other ways nowadays), but considering the case where you have a website 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 would normally give the name of your asset as a parameter. And within that function, it would mount the name to its asset
based on some flag, which would force it to force an update on all its clients.
More or less 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'd state it like this:
<img src="<?= asset('/img/futebol.jpg') ?>">
<script src="<?= asset('/js/app.js') ?>"></script>
This would make the url generated above:
/img/futebol.jpg?version=1.0.0
/js/app.js?version=1.0.0
Then, if you were to post a new version on the system, you would just trade your constant APP_VERSION
.
define('APP_VERSION', '1.0.1')
This would cause your assets to have a ?version=1.0.1
added, thus forcing the client's browser to get new information from the server.
Advantages of the above method :
Disadvantages :
?version=VERSÃO
different. src
or href
of your asset directly The second technique I had thought of was to update each asset individually. But to do this, you need to know the physical path of the asset through PHP.
The idea is the same as the above function, with a slight 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 filemtime
function is responsible for reading a file on the disk and informing, through an 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
Advantages
Disadvantages :
filemtime
function. Some minimalists would like to avoid so many calls to this function. But still, it is possible to bypass 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 displayed!
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);
}
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 head
tag of your page load the scripts in 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 place the version of the last deploy via Git.