数据缓存是指将一些 PHP 变量存储在缓存中,并在以后从缓存中检索它。它也是更高级缓存功能(例如 查询缓存 和 页面缓存)的基础。
以下代码是数据缓存的典型用法模式,其中 $cache
指的是 缓存组件
// try retrieving $data from cache
$data = $cache->get($key);
if ($data === false) {
// $data is not found in cache, calculate it from scratch
$data = $this->calculateSomething();
// store $data in cache so that it can be retrieved next time
$cache->set($key, $data);
}
// $data is available here
从 2.0.11 版本开始,缓存组件 提供了 getOrSet() 方法,简化了获取、计算和存储数据的代码。以下代码与前面的示例完全相同
$data = $cache->getOrSet($key, function () {
return $this->calculateSomething();
});
当缓存具有与 $key
关联的数据时,将返回缓存的值。否则,将执行传递的匿名函数来计算将被缓存并返回的值。
如果匿名函数需要来自外部作用域的一些数据,可以使用 use
语句传递它。例如
$user_id = 42;
$data = $cache->getOrSet($key, function () use ($user_id) {
return $this->calculateSomething($user_id);
});
注意:getOrSet() 方法也支持持续时间和依赖项。请参阅 缓存过期 和 缓存依赖 以了解更多信息。
数据缓存依赖于所谓的缓存组件,这些组件表示各种缓存存储,例如内存、文件、数据库。
缓存组件通常注册为 应用程序组件,以便可以全局配置和访问它们。以下代码展示了如何配置 cache
应用程序组件以使用 memcached 和两个缓存服务器
'components' => [
'cache' => [
'class' => 'yii\caching\MemCache',
'servers' => [
[
'host' => 'server1',
'port' => 11211,
'weight' => 100,
],
[
'host' => 'server2',
'port' => 11211,
'weight' => 50,
],
],
],
],
然后,您可以使用表达式 Yii::$app->cache
访问上述缓存组件。
如果未指定缓存组件,则 Yii 将使用 yii\caching\FileCache 作为默认值。
因为所有缓存组件都支持同一组 API,所以您可以通过在应用程序配置中重新配置它来将底层缓存组件替换为不同的组件,而无需修改使用缓存的代码。例如,您可以修改上述配置以使用 APC 缓存
'components' => [
'cache' => [
'class' => 'yii\caching\ApcCache',
],
],
提示:您可以注册多个缓存应用程序组件。组件名为
cache
,许多依赖缓存的类(例如 yii\web\UrlManager)默认使用它。
Yii 支持广泛的缓存存储。以下是总结
false
来禁用存储数据的序列化。Yii::$app->cache->get($key)
来尝试从缓存中检索数据,而无需担心 Yii::$app->cache
可能是 null
。提示:您可以在同一个应用程序中使用不同的缓存存储。一种常见的策略是使用基于内存的缓存存储来存储数据量小但经常使用的数据(例如统计数据),并使用基于文件或数据库的缓存存储来存储数据量大且使用频率低的数据(例如页面内容)。
所有缓存组件都具有相同的基类 yii\caching\Cache,因此支持以下 API
false
值。注意:不要直接缓存
false
布尔值,因为 get() 方法使用false
返回值来指示在缓存中找不到数据项。您可以将false
放入数组中并缓存此数组以避免此问题。
某些缓存存储(例如 MemCache、APC)支持以批处理模式检索多个缓存值,这可能会减少检索缓存数据所涉及的开销。multiGet() 和 multiAdd() API 用于利用此功能。如果底层缓存存储不支持此功能,则将对其进行模拟。
因为 yii\caching\Cache 实现 ArrayAccess
,所以缓存组件可以用作数组。以下是一些示例
$cache['var1'] = $value1; // equivalent to: $cache->set('var1', $value1);
$value2 = $cache['var2']; // equivalent to: $value2 = $cache->get('var2');
存储在缓存中的每个数据项都由一个键唯一标识。当您将数据项存储在缓存中时,必须为其指定一个键。稍后,当您从缓存中检索数据项时,应提供相应的键。
您可以使用字符串或任意值作为缓存键。当键不是字符串时,它将自动序列化为字符串。
定义缓存键的一种常见策略是将所有确定因素包含在数组中。例如,yii\db\Schema 使用以下键来缓存数据库表的架构信息
[
__CLASS__, // schema class name
$this->db->dsn, // DB connection data source name
$this->db->username, // DB connection login user
$name, // table name
];
如您所见,该键包含唯一指定数据库表所需的所有必要信息。
注意:通过 multiSet() 或 multiAdd() 存储在缓存中的值只能具有字符串或整数键。如果您需要设置更复杂的键,请通过 set() 或 add() 分别存储值。
当不同的应用程序使用相同的缓存存储时,应为每个应用程序指定唯一的缓存键前缀以避免缓存键冲突。这可以通过配置 yii\caching\Cache::$keyPrefix 属性来完成。例如,在应用程序配置中,您可以编写以下代码
'components' => [
'cache' => [
'class' => 'yii\caching\ApcCache',
'keyPrefix' => 'myapp', // a unique cache key prefix
],
],
为了确保互操作性,应仅使用字母数字字符。
存储在缓存中的数据项将永远保留在那里,除非由于某些缓存策略执行(例如缓存空间已满且最旧的数据被删除)而被删除。要更改此行为,您可以在调用 set() 以存储数据项时提供一个过期参数。该参数指示数据项在缓存中可以保持有效多长时间。当您调用 get() 以检索数据项时,如果已超过过期时间,则该方法将返回 false
,表示在缓存中找不到数据项。例如,
// keep the data in cache for at most 45 seconds
$cache->set($key, $data, 45);
sleep(50);
$data = $cache->get($key);
if ($data === false) {
// $data is expired or is not found in the cache
}
从 2.0.11 开始,如果您希望使用自定义缓存持续时间而不是默认的无限持续时间,则可以在缓存组件配置中设置 defaultDuration 值。这将允许您无需每次都将自定义 duration
参数传递给 set()。
除了过期设置外,缓存数据项也可能因所谓的缓存依赖项的变化而失效。例如,yii\caching\FileDependency 表示文件修改时间的依赖项。当此依赖项更改时,表示相应的文件已修改。结果,缓存中找到的任何过时的文件内容都应失效,并且 get() 调用应返回 false
。
缓存依赖项表示为 yii\caching\Dependency 后代类的对象。当您调用 set() 以将数据项存储在缓存中时,您可以传递关联的缓存依赖项对象。例如,
// Create a dependency on the modification time of file example.txt.
$dependency = new \yii\caching\FileDependency(['fileName' => 'example.txt']);
// The data will expire in 30 seconds.
// It may also be invalidated earlier if example.txt is modified.
$cache->set($key, $data, 30, $dependency);
// The cache will check if the data has expired.
// It will also check if the associated dependency was changed.
// It will return false if any of these conditions are met.
$data = $cache->get($key);
以下是可用缓存依赖项的摘要
注意:避免将 exists() 方法与依赖项一起使用。它不检查与缓存数据关联的依赖项(如果有)是否已更改。因此,对 get() 的调用可能会返回
false
,而 exists() 返回true
。
查询缓存是构建在数据缓存之上的特殊缓存功能。它用于缓存数据库查询的结果。
查询缓存需要一个 DB 连接 和一个有效的 cache
应用程序组件。查询缓存的基本用法如下所示,假设 $db
是一个 yii\db\Connection 实例
$result = $db->cache(function ($db) {
// the result of the SQL query will be served from the cache
// if query caching is enabled and the query result is found in the cache
return $db->createCommand('SELECT * FROM customer WHERE id=1')->queryOne();
});
查询缓存可用于 DAO 以及 ActiveRecord
$result = Customer::getDb()->cache(function ($db) {
return Customer::find()->where(['id' => 1])->one();
});
信息:某些 DBMS(例如 MySQL)还在 DB 服务器端支持查询缓存。您可以选择使用任一查询缓存机制。上面描述的查询缓存的优势在于,您可以指定灵活的缓存依赖项,并且可能效率更高。
从 2.0.14 开始,您可以使用以下快捷方式
(new Query())->cache(7200)->all();
// and
User::find()->cache(7200)->all();
查询缓存通过 yii\db\Connection 具有三个全局可配置选项
true
。请注意,要有效地开启查询缓存,您还需要拥有一个有效的缓存,如 queryCache 中所指定。'cache'
。只有存在有效的缓存应用程序组件时,才会启用查询缓存。如果您有多个需要利用查询缓存的 SQL 查询,则可以使用 yii\db\Connection::cache()。用法如下,
$duration = 60; // cache query results for 60 seconds.
$dependency = ...; // optional dependency
$result = $db->cache(function ($db) {
// ... perform SQL queries here ...
return $result;
}, $duration, $dependency);
匿名函数中的任何 SQL 查询都将根据指定的持续时间和依赖项进行缓存。如果在缓存中找到查询结果有效,则将跳过该查询,并从缓存中提供结果。如果未指定$duration
参数,则将使用queryCacheDuration的值。
有时在cache()
中,您可能希望禁用某些特定查询的查询缓存。在这种情况下,可以使用yii\db\Connection::noCache()。
$result = $db->cache(function ($db) {
// SQL queries that use query caching
$db->noCache(function ($db) {
// SQL queries that do not use query caching
});
// ...
return $result;
});
如果您只想对单个查询使用查询缓存,则可以在构建命令时调用yii\db\Command::cache()。例如:
// use query caching and set query cache duration to be 60 seconds
$customer = $db->createCommand('SELECT * FROM customer WHERE id=1')->cache(60)->queryOne();
您还可以使用yii\db\Command::noCache()禁用单个命令的查询缓存。例如:
$result = $db->cache(function ($db) {
// SQL queries that use query caching
// do not use query caching for this command
$customer = $db->createCommand('SELECT * FROM customer WHERE id=1')->noCache()->queryOne();
// ...
return $result;
});
查询缓存不适用于包含资源处理程序的查询结果。例如,在某些 DBMS 中使用BLOB
列类型时,查询结果将返回该列数据的资源处理程序。
某些缓存存储具有大小限制。例如,memcache 将每个条目的最大大小限制为 1MB。因此,如果查询结果的大小超过此限制,则缓存将失败。
当您需要使所有存储的缓存数据失效时,可以调用yii\caching\Cache::flush()。
您也可以通过调用yii cache/flush
从控制台刷新缓存。
yii cache
:列出应用程序中可用的缓存。yii cache/flush cache1 cache2
:刷新缓存组件cache1
、cache2
(您可以使用空格分隔多个组件名称)。yii cache/flush-all
:刷新应用程序中的所有缓存组件。yii cache/flush-schema db
:清除给定连接组件的数据库模式缓存。信息:控制台应用程序默认使用单独的配置文件。确保您的 Web 和控制台应用程序配置文件中具有相同的缓存组件,以达到预期的效果。
发现错别字或您认为此页面需要改进?
在 github 上编辑它 !
如果使用
where
,则此方法会出错子句
User::find()->where(['id' => $id])cache(7200)->all();
将返回原始的缓存结果,无论 ID 是否已更改。潜在的解决方案是 1,使用 where 子句作为缓存的哈希,或 2 允许除了缓存持续时间之外还指定缓存 ID。
注册 注册 或 登录 以发表评论。