如何使用php脚本给html中引用的js和css路径打上版本号


Posted in PHP onNovember 18, 2015

在搜索引擎中搜索关键字.htaccess 缓存,你可以搜索到很多关于设置网站文件缓存的教程,通过设置可以将css、js等不太经常更新的文件缓存在浏览器端,这样访客每次访问你的网站的时候,浏览器就可以从浏览器的缓存中获取css、js等,而不必从你的服务器读取,这样在一定程度上加快了网站的打开速度,又可以节约一下你的服务器流量。

具体文字说明不给大家多说了,下面通过代码实例给大家讲解。

比如

<link rel="stylesheet" type="text/css" href="./css/globel.css">
<script src="./js/config.js"></script>

中的href和src加上版本

<link rel="stylesheet" type="text/css" href="./css/globel.css?eslc-app=3-0-2">
<script src="./js/config.js?eslc-app=3-0-2"></script>

当然如果不是前后端 分离得干干净净的,就没必要这么额外的这样自己在写个脚本去打版本。

打版本的好处:

解决外部引用文件实时更新问题。比如

pc端上主要体现在 iframe中的外部引用文件不会实时更新。

wap端上部分app也是比如微信。 如果你的网页是嵌到自己的app,那也更不用说了。

用php写了个类

//生成版本
//清除版本
class ReplaceVersion{
 protected $filePostFixs = array();
 protected $versionName = null;
 protected $version = null;
 protected $path = null;
 /**
  * @param mixed $configs 
  * @param [type] $profix [description]
  * @param [type] $path  [description]
  */
 public function __construct($configs, $profix, $path){
  if (!$this->isCanRun()) {
   $this->error('必须在内网环境 10.10.0开头才可运行'); //exit;
  }
  $this->setVersion($configs);
  $this->setFilePostFix($profix);
  $this->path = $path;
 }
 protected function isCanRun(){
  if (strpos($_SERVER['HTTP_HOST'], '10.10.0') !== false) {
   return true;
  }
  return false;
 }
 /**
  * 匹配到script节点
  * @param array $match 匹配到的script
  * @return string 处理好的script
  */
 protected function callbackScript($match){
  //["<script src="../js/config.js?is=new"></script>", "../js/config.js", "?is=new"]
  /*/<script.*?src=\"(.*?)(\?.*?|\?)?\".*?><\/script>/*/
  $str = $match[0];
  $pattern = '/(<script.*?src=\")(.*)?(\"><\/script>)/';
  return $this->callbackMatch($str, $pattern);
 }
 /**
  * 匹配到css节点
  * @param array $match 匹配到的css
  * @return string 处理好的css
  */
 protected function callbackCss($match){
  // '<link rel="stylesheet" type="text/css" href="../css/globel.css">';
  $str = $match[0];
  $pattern = '/(<link.*?href=\")(.*)?(\".*?>)/';
  return $this->callbackMatch($str, $pattern);
 }
 /**
  * 回调模式匹配
  * @param string $str 
  * @param string $pattern
  * @return string  
  */
 protected function callbackMatch($str, $pattern){
  switch ($this->dealFlag) {
   case 'replace':
    return $this->replaceCallbackMatch($str, $pattern);
   case 'clean':
    return $this->cleanCallbackMatch($str, $pattern);
   default:
    $this->error('非法模式');
  }
 }
 /**
  * 替换版本
  * @param string $str 待处理的string
  * @param string $pattern 正则
  * @return string  处理后的string
  */
 protected function replaceCallbackMatch($str, $pattern){
  if (!preg_match($pattern, $str, $third)) {
   return $str;
  }
  $arr  = explode('?', $third[2]);
  $len  = count($arr);
  $versionName = $this->versionName;
  $version = $this->version;
  if ($len === 1) {//没有问号
   $arr[0] .= '?'. $versionName. '='. $version;
  }else{//有问号
   if (preg_match('/(^|\&)'. $versionName.'=(.*?)($|\&)/', $arr[1])) {//存在
    $arr[1] = preg_replace('/(^|\&)'. $versionName.'=(.*?)($|\&)/', '$1'. $versionName.'='. $version. '$3', $arr[1]);
    $arr[0] .= '?'. $arr[1];
   }else{//不存在
    $arr[0] .= '?'. $arr[1]. '&'. $versionName. '='. $version;
   }
  }
  return $third[1]. $arr[0]. $third[3];
 }
 /**
  * 清除版本
  * @param string $str 待清除的版本
  * @param string $pattern 正则
  * @return string  清除后的string
  */
 protected function cleanCallbackMatch($str, $pattern){
  if (!preg_match($pattern, $str, $third)) {
   return $str;
  }
  $arr  = explode('?', $third[2]);
  $len  = count($arr);
  $versionName = $this->versionName;
  if ($len > 1 && strpos($arr[1], $versionName. '=') !== false) {
   $arr[1] = preg_replace('/(^|\&)'. $versionName.'=(.*?)($|\&)/', '$1', $arr[1]);
   substr($arr[1], -1) === '&' && ($arr[1] = substr($arr[1], 0, -1));
   $arr[0] .= strlen($arr[1]) > 0 ? '?'. $arr[1] : '';
   $str = $third[1]. $arr[0]. $third[3];
  }
  return $str;
 }
 /**
  * 执行
  */
 protected function run(){
  if ($this->path == '') {
   $this->error('empty path');
   return ;
  }
  if (is_dir($this->path)) {
   $this->setDirFilesVersion( $this->path );
  }else if(is_file($this->path)){
   $this->setFileVersion( $this->path );
  }else{
   $this->error('error path');
  }
 }
 /**
  * 添加版本
  */
 public function replace(){
  $this->dealFlag = 'replace';
  $this->run();
  echo 'replace success';
 }
 /**
  * 清除版本
  */
 public function clean(){
  $this->dealFlag = 'clean';
  $this->run();
  echo 'clean success';
 }
 protected function success(){
 }
 protected function error($errorMsg){
  echo $errorMsg;
  exit();
 }
 protected function setDirFilesVersion($dir){
  $handle = null;
  $file  = null;
  if ( $handle = opendir($dir)) {
   while ( false !== ($file = readdir($handle)) ) {
    if ($file === '.' || $file === '..' || strpos($file, '.') === -1 ) {continue;}
    $this->setFileVersion($file);
   }
  }
 }
 protected function setFileVersion($file){
  $temp = null;
  /*$pattern = '/<script.*?src=\"(.*?)(\?.*?|\?)?\".*?><\/script>/';*/
  $temp = explode('.', $file) ;
  if ( ! $this->isNeedReplacePostFix(array_pop( $temp )) ) {return;}
  $content = null;
  $content = file_get_contents($file);
  $content = preg_replace_callback('/<script.*?><\/script>/', array(&$this, 'callbackScript'), $content);
  $content = preg_replace_callback('/<link.*?type="text\/css".*?>/', array(&$this, 'callbackCss'), $content);
  // highlight_string($content);
  file_put_contents($file, $content);
 }
 /**
  * 获得版本
  * @param mixed $configs array( 'versionName' : 'version') || $versionName
  */
 protected function setVersion($configs){
  // last_wap_version  = '3-0-0', 
  // wap_version = '3-0-1',
  if (is_array($configs) && $configs > 0) {
   foreach ($configs as $key => $value) {
    $this->version = $value;
    $this->versionName = $key;
   }
  }else if(is_string($configs) && $configs != ''){
   $configs = explode(',', $configs);
   $this->versionName = $configs[0];
   count($configs) == 2 && ($this->version = $configs[1]);
  }else{
   $this->error('the version is empty');
  }
 }
 /**
  * 通过后缀判断该文件是否要添加或清除版本
  * @param string $profix 后缀
  * @return boolean  true | false
  */
 protected function isNeedReplacePostFix($profix){
  if (in_array($profix, $this->filePostFixs)) {
   return true;
  }
  return false;
 }
 /**
  * 设置需要操作的后缀
  */
 public function setFilePostFix($profix){
  if (is_array($profix)) {
   count($profix) > 0 && ( $this->filePostFixs = array_merge($this->filePostFixs, $profix) );
  }else if(is_string($profix)){
   $this->filePostFixs[] = $profix;
  }
 }
}

使用:

$dir  = __DIR__;
$is_clean = false;
//$is_clean = true;
//第一个参就是版本信息, 第二个就是要匹配的文件后缀, 第三个是要匹配的目录或者文件
if ($is_clean) {//清除版本
 $configs = 'eslc-wap';
 $replaceObj = new ReplaceVersion($configs, array('html'), $dir);
 $replaceObj->clean();
}else{//添加或替换版本
 $configs = array('eslc-wap' => '1.0.1');//也可以写成 $configs = 'eslc-wap, 1.0.1';
 $replaceObj = new ReplaceVersion($configs, array('html'), $dir);
 $replaceObj->replace();
}
PHP 相关文章推荐
substr()函数中文版
Oct 09 PHP
php判断上传的Excel文件中是否有图片及PHPExcel库认识
Jan 11 PHP
浅析使用Turck-mmcache编译来加速、优化PHP代码
Jun 20 PHP
PHP图片上传代码
Nov 04 PHP
destoon利用Rewrite规则设置网站安全
Jun 21 PHP
php通过修改header强制图片下载的方法
Mar 24 PHP
PHP获取数组最大值下标的方法
May 12 PHP
深入php内核之php in array
Nov 10 PHP
给WordPress的编辑后台添加提示框的代码实例分享
Dec 25 PHP
PHP中file_exists使用中遇到的问题小结
Apr 05 PHP
PHP给文字内容中的关键字进行套红处理
Apr 12 PHP
php设计模式之适配器模式实例分析【星际争霸游戏案例】
Apr 07 PHP
php生成唯一数字id的方法汇总
Nov 18 #PHP
基于PHP给大家讲解防刷票的一些技巧
Nov 18 #PHP
使用PHP uniqid函数生成唯一ID
Nov 18 #PHP
使用PHP实现生成HTML静态页面
Nov 18 #PHP
php+ajax无刷新上传图片实例代码
Nov 17 #PHP
php计算年龄精准到年月日
Nov 17 #PHP
php实现简单的上传进度条
Nov 17 #PHP
You might like
php为什么选mysql作为数据库? Mysql 创建用户方法
2007/07/02 PHP
PHP实现的线索二叉树及二叉树遍历方法详解
2016/04/25 PHP
支付宝服务窗API接口开发php版本
2016/07/20 PHP
laravel框架创建授权策略实例分析
2019/11/22 PHP
JavaScript 版本自动生成文章摘要
2008/07/23 Javascript
javascript笔试题目附答案@20081025_jb51.net
2008/10/26 Javascript
javascript Array.remove() 数组删除
2009/08/06 Javascript
在Ajax中使用Flash实现跨域数据读取的实现方法
2010/12/02 Javascript
让低版本浏览器支持input的placeholder属性(js方法)
2013/04/03 Javascript
js获取视频时长代码
2014/04/10 Javascript
javascript中数组的定义及使用实例
2015/01/21 Javascript
JS中prototype的用法实例分析
2015/03/19 Javascript
jquery插件jquery.nicescroll实现图片无滚动条左右拖拽的方法
2015/08/10 Javascript
javascript中new关键字详解
2015/12/14 Javascript
jquery文字填写自动高度的实现方法
2016/11/07 Javascript
详解jquery选择器的原理
2017/08/01 jQuery
原生JS实现循环Nodelist Dom列表的4种方式示例
2018/02/11 Javascript
探索JavaScript中私有成员的相关知识
2019/06/13 Javascript
js模拟F11页面全屏显示
2019/09/17 Javascript
Node绑定全局TraceID的实现方法
2019/11/14 Javascript
ES11屡试不爽的新特性,你用上了几个
2020/10/21 Javascript
python获取beautifulphoto随机某图片代码实例
2013/12/18 Python
pytorch 转换矩阵的维数位置方法
2018/12/08 Python
Python中遍历列表的方法总结
2019/06/27 Python
Python使用matplotlib绘制Logistic曲线操作示例
2019/11/28 Python
举例详解HTML5中使用JSON格式提交表单
2015/06/16 HTML / CSS
印度在线杂货店:bigbasket
2018/08/23 全球购物
英国日常交易网站:Wowcher
2018/09/04 全球购物
应届护士推荐信
2013/11/16 职场文书
中医专业应届生求职信
2013/11/17 职场文书
国际金融专业大学生职业生涯规划书
2013/12/28 职场文书
给分销商的致歉信
2014/01/14 职场文书
职业生涯规划书怎么写?
2014/09/14 职场文书
领导干部贪图享乐整改措施
2014/09/21 职场文书
2015毕业寄语大全
2015/02/26 职场文书
2019年大学生职业生涯规划书最新范文
2019/03/25 职场文书