支付宝扫一扫付款
微信扫一扫付款
(微信为保护隐私,不显示你的昵称)
Cache Pools(缓存池)是缓存元素(cache items)的逻辑宝库(logical repositories)。它们对缓存元素上的“全部常规操作”进行操作,比如存储它们或是寻找它们。缓存池是独立于真实的缓存实现过程(cache implementation)之外的。因此,程序可以在缓存架构“从文件系统缓存改换为Redis缓存或是数据库缓存”的情况下保持使用相同的缓存池。
缓存池通过 cache adapters 来创建, 缓存适配器是实现了 AdapterInterface
的类。本组件提供几种适配器让你拿来就用。
这个adapter只在测试时有用,因为内容是存在内存中,不以任何方式持久化。另外,本文后面解释的一些功能在这里并不适用,比如延时存储(deferred saves):
1 2 3 4 5 6 7 8 9 10 11 12 | use Symfony\Component\Cache\Adapter\ArrayAdapter;
$cache = new ArrayAdapter(
// in seconds; applied to cache items that don't define their own lifetime
// 0 means to store the cache items indefinitely (i.e. until the current PHP process finishes)
// 以秒计;适用于没有定义自身生命周期的缓存元素
// 0 代表把缓存元素地“未定义”地存储(如,只到当前PHP进程结束为止)
$defaultLifetime = 0,
// if ``true``, the values saved in the cache are serialized before storing them
// 如果是true,存入缓存的值将先被序列化再存入
$storeSerialized = true
); |
这个适配器在你希望改进程序性能“但却不能在服务器上安装诸如APC或Redis”时有用。适配器把内容当作“本地文件系统的目录群组”中的常规文件进行存储:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cache = new FilesystemAdapter(
// the subdirectory of the main cache directory where cache items are stored
// 缓存元素所在的缓存主目录中的子目录
$namespace = '',
// in seconds; applied to cache items that don't define their own lifetime
// 0 means to store the cache items indefinitely (i.e. until the files are deleted)
// 以秒计;适用于没有定义自身生命周期的缓存元素
// 0 代表把缓存元素地“未定义”地存储(如,只到文件被删除时为止)
$defaultLifetime = 0,
// the main cache directory (the application needs read-write permissions on it)
// if none is specified, a directory is created inside the system temporary directory
// 缓存主目录(需要读写权限)
// 如果没有被指定,将在系统的临时目录中新建一个目录
$directory = null |
这个适配器可以显著提升程序的性能,因为内容被缓存在服务器的共享内存中,速度远远高于文件系统。它必须要安装PHP APCu扩展。当进行密集写入和删除的操作时不推荐使用,因为这会在APCu内存中产生碎片,以至大幅降低性能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | use Symfony\Component\Cache\Adapter\ApcuAdapter;
$cache = new ApcuAdapter(
// the string prefixed to the keys of the items stored in this cache
// 缓存中的元素的键的字符串前缀
$namespace = '',
// in seconds; applied to cache items that don't define their own lifetime
// 0 means to store the cache items indefinitely (i.e. until the APC memory is deleted)
// 以秒计;适用于没有定义自身生命周期的缓存元素
// 0 代表把缓存元素地“未定义”地存储(如,只到APC内存被删除时为止)
$defaultLifetime = 0,
// if present, this string is added to the namespace to simplify the
// invalidation of the entire cache (e.g. when deploying the application)
// 如果提供此参数,字符串被添加到命名空中,以简化整个缓存的“无效化”(比如在部署程序时)
$version = null
); |
这个适配器把内容存到服务器内存中。不像APCu adapter,它不受当前服务器的共享内存的限制,所以如果有必要,你可以把内容存储到一个服务器集群。
它需要安装Redis,并创建一个实现了 \Redis
, \RedisArray
, \RedisCluster
或 \Predis
类的连接(connection)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | use Symfony\Component\Cache\Adapter\RedisAdapter;
$cache = new RedisAdapter(
// the object that stores a valid connection to your Redis system
// 用于“把一个有效连接存储到你的Redis系统”的对象
\Redis $redisConnection,
// the string prefixed to the keys of the items stored in this cache
// 缓存中的元素的键的字符串前缀
$namespace = '',
// in seconds; applied to cache items that don't define their own lifetime
// 0 means to store the cache items indefinitely (i.e. until the Redis memory is deleted)
// 以秒计;适用于没有定义自身生命周期的缓存元素
// 0 代表把缓存元素地“未定义”地存储(如,只到Redis内存被删除时为止)
$defaultLifetime = 0
); |
这个适配器允许整合任何数量的前述适配器。缓存元素从包含它们的第一个适配器中被取出。此外,缓存元素被存储在所有给定的适配器中,因此这是一种创建“缓存复制”(cache replication)的简单方式:
1 2 3 4 5 6 7 8 | use Symfony\Component\Cache\Adapter\ApcuAdapter;
use Symfony\Component\Cache\Adapter\ChainAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$apcCache = new ApcuAdapter();
$fileCache = new FilesystemAdapter();
$cache = new ChainAdapter(array($apcCache, $fileCache)); |
当元素未在第一个适配器中被找到,但却在相邻的适配器中找到时,ChainAdapter
确保这个被取出的元素能够被存到“丢失它”的所有适配器中。由于不可能得知缓存元素的过期日期和时间,ChainAdapter
的第二个可选参数是用于那些缓存元素的默认生命周期(默认是 0
)。
这个适配器可用于整合你程序中“并非Symfony Cache组件创建”的缓存池。只要这些缓存池实现了 CacheItemPoolInterface
接口,适配器就允许你从外部缓存中取得元素,然后把它们存到你你程序中的Symfony缓存中。
1 2 3 4 | use Symfony\Component\Cache\Adapter\ProxyAdapter;
// ... create $nonSymfonyCache somehow
$cache = new ProxyAdapter($nonSymfonyCache); |
这个适配器接收两个附加的可选参数:命名空间(namespace,默认是 ''
)和默认的生命周期(lifetime,默认是 0
)。
此适配器的另一个使用场合,取得缓存命中(getHits()
)和缓存丢失(getMisses()
)的统计(statistics)和度量(metrics)。
这个适配器对任何一个 Doctrine Cache provider进行打包,以便你能在程序中使用它们,如同它们就是Symfony缓存适配器一样:
1 2 3 4 5 6 | use Doctrine\Common\Cache\SQLite3Cache;
use Symfony\Component\Cache\Adapter\DoctrineAdapter;
$sqliteDatabase = new \SQLite3(__DIR__.'/cache/data.sqlite');
$doctrineCache = new SQLite3Cache($sqliteDatabase, 'tableName');
$symfonyCache = new DoctrineAdapter($doctrineCache); |
这个适配器接收两个附加的可选参数:命名空间(namespace,默认是 ''
)和默认的生命周期(lifetime,默认是 0
),并且对它们进行适配,以便能够在背后的Doctrine缓存中工作。
缓存池定义了三个方法来寻找缓存元素。最常见的方法是 getItem()
,它返回“通过给定的键来识别”的缓存元素:
1 2 3 4 | use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cache = new FilesystemAdapter('app.cache');
$latestNews = $cache->getItem('latest_news'); |
如果没有元素是给定键所定义,本方法并非返回一个 null
值而是一个空的实现了 CacheItem
类的对象。
如果你需要同时取出若干缓存元素,使用 getItems(array($key1, $key2, ...))
方法来替代:
1 2 | // ...
$stocks = $cache->getItems(array('AAPL', 'FB', 'GOOGL', 'MSFT')); |
再一次,如果其中的任何一个键并不能呈现一个有效的缓存元素,你不会得到 null
值,而是一个空的 CacheItem
对象。
最后一个关于取出缓存元素的方法是 hasItem($key)
,它返回 true
,如果并没有“被这个给定的键”所定义的缓存元素的话。
1 2 | // ...
$hasBadges = $cache->hasItem('user_'.$userId.'_badges'); |
最常用的用来存储缓存元素的方法是 save()
,它把元素立即存入缓存 (并且在元素已存入时返回 true
或者出错时返回 false
):
1 2 3 4 | // ...
$userFriends = $cache->get('user_'.$userId.'_friends');
$userFriends->set($user->getFriends());
$isSaved = $cache->save($userFriends); |
有时你为了提高程序性能而倾向于“不立即存储对象”。此时,使用 saveDeferred()
方法来标记缓存元素为“已为持久化准备完毕”然后调用 commit()
方法,当你要把它们全部持久化时:
1 2 3 4 5 6 7 8 | // ...
$isQueued = $cache->saveDeferred($userFriends);
// ...
$isQueued = $cache->saveDeferred($userPreferences);
// ...
$isQueued = $cache->saveDeferred($userRecentProducts);
// ...
$isSaved = $cache->commit(); |
saveDeferred()
方法返回 true
,当缓存元素已经被成功添加到 "persist queue"(入库序列)时,否则返回 false
。 commit()
方法返回 true
,当被挂起的全部元素被存储完毕时,否则返回 false
。
缓存池提供了删除缓存元素、部分元素、全部元素的方法,最为常见的是 deleteItem()
,它删除由给定的键所指定的缓存元素 (成功删除时,或元素不存在时,它返回 true
,否则返回 false
):
1 2 | // ...
$isDeleted = $cache->deleteItem('user_'.$userId); |
使用 deleteItems()
方法来同时删除若干缓存元素 (它仅在全部元素被删除时返回 true
,其中的某一个或部分元素不存在时也是如此):
1 2 | // ...
$areDeleted = $cache->deleteItems(array('category1', 'category2')); |
最后,删除缓存池中的全部缓存元素,使用 clear()
方法 (它在全部元素被成功删除时返回 true
):
1 2 | // ...
$cacheIsEmpty = $cache->clear(); |
本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。