How can I force refresh after deploy?

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 would be obliged to update everything that had changed, such as images, CSS, JS, etc.

p>

How can I do this?

    
asked by anonymous 22.02.2018 / 20:54

2 answers

3

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.

Technique 1: Forcing the update of all assets

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 :

  • You change in one place and everything is updated.
  • No need to change folder structure or use libraries to do the job

Disadvantages :

  • If you just want to update a file, it would not be possible, because with the version change, all assets would receive the addition of a ?version=VERSÃO different.
  • You have to call a function instead of simply declaring the src or href of your asset directly

Technique 2: Forcing the individual update

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

  • Update each file individually
  • You do not need to change any values manually. If the file is modified then it will always be updated in the browser

Disadvantages :

  • Impossible to use absolute url in the function, since we use part of the path to build the physical path of the file to get the modification date.
  • With each added asset, it will call the 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);
}
    
24.08.2018 / 20:20
2

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.

    
24.08.2018 / 19:36