| }
OUTPUT: <link xhref="/css/group.v1234567890.css" mce_href="/css/group.v1234567890.css" rel="stylesheet" type="text/css" />
对每个链接到的资源文件,我们得到它在磁盘上的路径,检查它的mtime(文件最后修改的日期和时间),然后把这个时间当作版本号插入到url中。对于低流量的站点(它们的stat操作开销不大)或者开发环境来说,这个方案不错,但对于高容量的环境就不适用了——因为每次stat操作都要磁盘读取(导致服务器负载升高)。 解决方案相当简单。在大型系统中每个资源都已经有了一个版本号,就是版本控制的修订号(你们应该使用了版本控制,对吧?)。当我们建立站点预备部署的时候,可以轻易的查到每个文件的修订号,写在一个静态配置文件里。
<?php $GLOBALS['config']['resource_versions'] = array( '/images/foo.gif' => '2.1', '/css/main.css' => '1.27', '/javascript/md5.js' => '6.1.4',); ?>
当我们发布产品时,可以修改模板函数来使用版本号。
<?php function smarty_version($args){ if ($GLOBALS['config']['is_dev_site']){ $stat = stat($GLOBALS['config']['site_root'].$args['src']); $version = $stat['mtime']; }else{ $version = $GLOBALS['config']['resource_versions'][$args['src']]; } echo preg_replace('!.([a-z] ?)$!', ".v$version.$1", $args['src']);} ?>
就这样,不需要改文件名,也不需要记住改了哪些文件——当文件有新版本发布时它的url就会自动更新——有意思吧?我们就快搞定了。 只欠东风
之前谈到为静态文件发送超长周期(very-long-period)的缓存header时曾说过,假如不用php输出,就不能轻易的发送缓存header。很显然,有两个办法可以解决:用php输出,或者让apache来做。 php出马,手到擒来。我们要做的仅仅是改变rewrite规则,把静态文件指向php脚本,用php在输出文件内容之前发送header。
Apache: RewriteRule ^/(.*.)v[0-9.] .(css|js|gif|png|jpg)$ /redir.php?path=$1$2 [L]
PHP: header("Expires: ".gmdate("D, d M Y H:i:s", time() 315360000)." GMT"); header("Cache-Control: max-age=315360000");# 忽略带有“..”的路径 if (preg_match('!..!', $_GET[path])){ go_404(); }# 保证路径开头是确定的目录 if (!preg_match('!^(javascript|css|images)!', $_GET[path])){ go_404(); }# 文件不存在? if (!file_exists($_GET[path])){ go_404(); }# 发出一个文件类型 header$ext = array_pop(explode('.', $_GET[path])); switch ($ext){ case 'css': header("Content-type: text/css"); break; case 'js' : header("Content-type: text/javascript"); break; case 'gif': header("Content-type: image/gif"); break; case 'jpg': header("Content-type: image/jpeg"); break; case 'png': header("Content-type: image/png"); break; default: header("Content-type: text/plain"); } # 输出文件内容 echo implode('', file($_GET[path])); function go_404(){ header("HTTP/1.0 404 File not found"); exit; }
这个方案有效,但并不出色。(因为)跟apache相比,php需要更多内存和执行时间。另外,我们还得小心防止可能由path参数传递伪造值引起的 exploits。为避免这些问题,应该用apache直接发送header。rewrite规则语句答应当规则匹配时设置环境变量(environment variable),当给定的环境变量设置后,Header命令就可以添加header。结合以下两条语句,我们就把rewrite规则和header设置绑定在了一起:
|
| 共8页: 上一页 [1] [2] [3] [4] [5] [6] 7 [8] 下一页 |
评论加载中…