在PHP中自动版本化JavaScript和CSS文件

How often have your clients complained to you about not being able to see the new changes you have made to their website? This happens to me a lot, and it seems to be quite a common occurrence for other web developers too. For example, perhaps I’ve just updated the JavaScript and/or CSS files, but my client’s browser is still using their cached version (preventing them from seeing any of the new changes) and they’re confused as to why they’re looking at an older site.

您的客户多久抱怨您看不到您对其网站所做的新更改? 这在我身上经常发生,对于其他Web开发人员来说,这似乎也很常见。 例如,也许我刚刚更新了JavaScript和/或CSS文件,但是我客户的浏览器仍在使用它们的缓存版本(防止它们看到任何新更改),并且对于为什么要查找它们感到困惑在较旧的网站上。

The most common way to tackle this issue is to version JavaScript and CSS files. Unfortunately for me, however, manually versioning all the files every time that I have to perform a deploy is boring and error-prone. Happily, there is a way around this that this article will dive into, so without further ado let’s explore two ways to automatically version JavaScript and CSS Files in PHP.

解决此问题的最常见方法是对JavaScript和CSS文件进行版本控制 。 但是,对我来说不幸的是,每次必须执行部署时手动对所有文件进行版本控制很无聊且容易出错。 令人高兴的是,本文将采用一种解决方法,因此,不用费劲,让我们探索两种在PHP中自动对JavaScript和CSS文件进行版本控制的方法。

Please note: While we are going to look at how to auto-version JavaScript and CSS files, the two following methods could easily be adapted to images (or any other files) as well.

请注意:虽然我们将研究如何自动版本化JavaScript和CSS文件,但是以下两种方法也可以轻松地适用于图像(或任何其他文件)。

方法1 (Method 1)

This method aims at harnessing the modification time of a JavaScript or CSS file to implement auto-versioning. The idea is to automatically append a query string to each of our files. This query string represents their own version, whose number is determined from their modification time. In so doing, we are tricking the browser into thinking that new files are being specified when, in fact, browsers usually simply look at the full name of each file (meaning that they will be cached accordingly).

此方法旨在利用JavaScript或CSS文件的修改时间来实现自动版本控制。 这个想法是将查询字符串自动附加到我们的每个文件中。 此查询字符串表示其自己的版本,其版本号由其修改时间确定。 这样一来,我们实际上是在诱使浏览器通常只是简单地查看每个文件的全名(这意味着它们将被相应地缓存)时,欺骗浏览器以为正在指定新文件。

This can be easily achieved with some lines of code, as follows:

这可以通过一些代码行轻松实现,如下所示:

<?php
  
/**
 *  Given a valid file location (it must be an path starting with "/"), i.e. "/css/style.css",
 *  it returns a string containing the file's mtime as query string, i.e. "/css/style.css?v=0123456789".
 *  Otherwise, it returns the file location.
 *
 *  @param $file  the file to be loaded.
 */
function auto_version($file) {
    // if it is not a valid path (example: a CDN url)
    if (strpos($file, '/') !== 0 || !file_exists($_SERVER['DOCUMENT_ROOT'] . $file)) return $file;


    // retrieving the file modification time
    // https://www.php.net/manual/en/function.filemtime.php
    $mtime = filemtime($_SERVER['DOCUMENT_ROOT'] . $file);


    return sprintf("%s?v=%d", $file, $mtime);
}

By inspecting the HTML code of the web page, we will see:

通过检查网页HTML代码,我们将看到:

<link rel="stylesheet" href="/css/myCSSFile1.css?v=1593800287" type="text/css">
<link rel="stylesheet" href="/css/myCSSFile2.css?v=1693189689" type="text/css">
<link rel="stylesheet" href="/css/myCSSFile3.css?v=1933020647" type="text/css">

The downside of this method is that some browsers may ignore the appended query strings and use the previously cached copy, instead of the new version with the same files. This is why we are going to run through a second method.

此方法的缺点是某些浏览器可能会忽略附加的查询字符串,而使用以前缓存的副本,而不是具有相同文件的新版本。 这就是为什么我们要尝试第二种方法的原因。

方法2 (Method 2)

This method is more complex and aims to automatically append the version of each JavaScript and CSS file directly to their name. Again, the version number is generated using the file modification time. Firstly, we need to add some additional lines to our .htaccess file, since some mod_rewrite rules to allow version numbers in our file names are required:

此方法更为复杂,旨在将每个JavaScript和CSS文件的版本直接自动附加到其名称中。 同样,使用文件修改时间生成版本号。 首先,我们需要在.htaccess文件中添加一些额外的行,因为需要一些mod_rewrite规则来允许文件名中包含版本号:

RewriteEngine on
RewriteRule ^(.*)\.[\d]{10}\.(css|js)$ $1.$2 [L]

Apache will now automatically redirect any files with 10 digits (since 10 digits cover all timestamps from 9/9/2001 to 11/20/2286) before a .css or .js extension back to just the filename and extension. With these rules in place, the URL .../style.css can now be rewritten as .../style.0123456789.css and Apache will see those as the exact same files. Additionally, as the second file has a different name to the first one, the browser will ignore the previously cached copy of the file.

现在,Apache将自动将任何具有10位数字的文件重定向(因为10位数字覆盖了从9/9/2001到11/20/2286的所有时间戳),然后才将.css.js扩展名返回到文件名和扩展名。 有了这些规则,URL .../style.css现在可以重写为.../style.0123456789.css ,Apache会将它们视为完全相同的文件。 此外,由于第二个文件的名称与第一个文件不同,因此浏览器将忽略该文件的先前缓存的副本。

Now, we need to change our CSS and JavaScript import logic. This can be easily achieved with a custom PHP function:

现在,我们需要更改CSS和JavaScript导入逻辑。 这可以通过自定义PHP函数轻松实现:

<?php


/**
 *  Given a valid file location (it must be an path starting with "/"), i.e. "/css/style.css",
 *  it returns a string containing the file's mtime, i.e. "/css/style.0123456789.css".
 *  Otherwise, it returns the file location.
 *
 *  @param $file  the file to be loaded.
 */
function auto_version($file) {
    // if it is not a valid path (example: a CDN url)
    if (strpos($file, '/') !== 0 || !file_exists($_SERVER['DOCUMENT_ROOT'] . $file)) return $file;


    // retrieving the file modification time
    // https://www.php.net/manual/en/function.filemtime.php
    $mtime = filemtime($_SERVER['DOCUMENT_ROOT'] . $file);


    return preg_replace('{\\.([^./]+)$}', ".$mtime.\$1", $file);
}

By inspecting the HTML code of the web page, we will see:

通过检查网页HTML代码,我们将看到:

<link rel="stylesheet" href="/css/myCSSFile1.1593800287.css" type="text/css">
<link rel="stylesheet" href="/css/myCSSFile2.1693189689.css" type="text/css">
<link rel="stylesheet" href="/css/myCSSFile3.1933020647.css" type="text/css">

结论 (Conclusion)

Not being able to view new updates to websites can be a confusing experience for clients, not to mention frustrating for web developers! There is a way to overcome this issue, however, as my article has explored. Using the above methods, the browser will be able to cache our JavaScript and CSS files, but when any changes are made it will not use their cached copies (meaning that we will not run into issues with the clients being unable to view new changes to the site).

无法查看网站的新更新可能会使客户感到困惑,更不用说让Web开发人员感到沮丧了! 但是,正如我的文章所探讨的,有一种方法可以解决此问题。 使用上述方法,浏览器将能够缓存我们JavaScript和CSS文件,但是在进行任何更改时,它将不会使用其缓存副本(这意味着我们不会因客户端无法查看新的更改而遇到问题。网站)。

I hope that you found this article helpful, thanks for reading! Feel free to reach out to me for any questions, comments, or suggestions.

希望本文对您有所帮助,感谢您的阅读! 如有任何问题,意见或建议,请随时与我联系。

翻译自: https://codeburst.io/auto-versioning-javascript-and-css-files-in-php-892d05c82d58

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值