感谢你来到这里
我真的很激动
盼望,能有你的支持
捐赠可扫描二维码转账支付
支付宝扫一扫付款
微信扫一扫付款
(微信为保护隐私,不显示你的昵称)
3.1 对自定义版本策略的支持从Symfony 3.1起被引入。
Asset versioning(资源版本)是一种技巧,它通过对静态资源(CSS, JavaScript和图片等)的URL添加版本识别符(version identifier),提升了web程序性能。当资源内容发生改变时,其识别符也跟着改变并强制浏览器来重新下载,而不是复用缓存中的资源。
Symfony支持asset versioning(资源版本),靠的是 version 和 version_format 配置选项。如果你的程序需要更多的高级版本(处理),比如基于一些外部信息来动态生成版本,你可以创建自己的版本策略。
下面的例子展示了如何创建兼容 gulp-buster 的版本策略(version strategy)。这个工具定义的配置文件被称为 busters.json
,将每一个资源文件映射到相应内容的hash值上:
1 2 3 4 | {
"js/script.js": "f9c7afd05729f10f55b689f36bb20172",
"css/style.css": "91cd067f79a5839536b46c494c4272d8"
} |
资源(assets)的版本策略,是实现了 VersionStrategyInterface
接口的PHP类。本例中,类的构造器把由 gulp-buster 生成的清单文件(manifest file),以及所生成的版本字符串格式,作为构造参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | // src/AppBundle/Asset/VersionStrategy/GulpBusterVersionStrategy.php
namespace AppBundle\Asset\VersionStrategy;
use Symfony\Component\Asset\VersionStrategy\VersionStrategyInterface;
class GulpBusterVersionStrategy implements VersionStrategyInterface
{
/**
* @var string
*/
private $manifestPath;
/**
* @var string
*/
private $format;
/**
* @var string[]
*/
private $hashes;
/**
* @param string $manifestPath
* @param string|null $format
*/
public function __construct($manifestPath, $format = null)
{
$this->manifestPath = $manifestPath;
$this->format = $format ?: '%s?%s';
}
public function getVersion($path)
{
if (!is_array($this->hashes)) {
$this->hashes = $this->loadManifest();
}
return isset($this->hashes[$path]) ? $this->hashes[$path] : '';
}
public function applyVersion($path)
{
$version = $this->getVersion($path);
if ('' === $version) {
return $path;
}
$versionized = sprintf($this->format, ltrim($path, '/'), $version);
if ($path && '/' === $path[0]) {
return '/'.$versionized;
}
return $versionized;
}
private function loadManifest(array $options)
{
return json_decode(file_get_contents($this->manifestPath), true);
}
} |
在创建了PHP的策略文件之后,把它注册成Symfony服务:
1 2 3 4 5 6 7 8 | # app/config/services.yml
services:
app.assets.versioning.gulp_buster:
class: AppBundle\Asset\VersionStrategy\GulpBusterVersionStrategy
arguments:
- "%kernel.root_dir%/../busters.json"
- "%%s?version=%%s"
public: false |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <!-- app/config/services.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd"
>
<services>
<service id="app.assets.versioning.gulp_buster"
class="AppBundle\Asset\VersionStrategy\GulpBusterVersionStrategy" public="false">
<argument>%kernel.root_dir%/../busters.json</argument>
<argument>%%s?version=%%s</argument>
</service>
</services>
</container> |
1 2 3 4 5 6 7 8 9 10 11 12 13 | // app/config/services.php
use Symfony\Component\DependencyInjection\Definition;
$definition = new Definition(
'AppBundle\Asset\VersionStrategy\GulpBusterVersionStrategy',
array(
'%kernel.root_dir%/../busters.json',
'%%s?version=%%s',
)
);
$definition->setPublic(false);
$container->setDefinition('app.assets.versioning.gulp_buster', $definition); |
最后,对程序中的所有资源,或一部分 asset package 来开启这个全新的资源版本,这得益于 version_strategy 选项:
1 2 3 4 5 | # app/config/config.yml
framework:
# ...
assets:
version_strategy: 'app.assets.versioning.gulp_buster' |
1 2 3 4 5 6 7 8 9 10 11 12 | <!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:framework="http://symfony.com/schema/dic/symfony"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
<framework:config>
<framework:assets version-strategy="app.assets.versioning.gulp_buster" />
</framework:config>
</container> |
本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。