目录
深入解析PHP的Yii框架中的缓存功能,yii框架
您可能感兴趣的文章:
首页 php教程 php手册 深入解析PHP的Yii框架中的缓存功能,yii框架

深入解析PHP的Yii框架中的缓存功能,yii框架

Jun 13, 2016 am 08:42 AM
yii 缓存

深入解析PHP的Yii框架中的缓存功能,yii框架

数据缓存是指将一些 PHP 变量存储到缓存中,使用时再从缓存中取回。它也是更高级缓存特性的基础,例如查询缓存和内容缓存。

如下代码是一个典型的数据缓存使用模式。其中 $cache 指向缓存组件:

// 尝试从缓存中取回 $data 
$data = $cache->get($key);

if ($data === false) {

  // $data 在缓存中没有找到,则重新计算它的值

  // 将 $data 存放到缓存供下次使用
  $cache->set($key, $data);
}

// 这儿 $data 可以使用了。

登录后复制

缓存组件

数据缓存需要缓存组件提供支持,它代表各种缓存存储器,例如内存,文件,数据库。

缓存组件通常注册为应用程序组件,这样它们就可以在全局进行配置与访问。如下代码演示了如何配置应用程序组件 cache 使用两个 memcached 服务器:

'components' => [
  'cache' => [
    'class' => 'yii\caching\MemCache',
    'servers' => [
      [
        'host' => 'server1',
        'port' => 11211,
        'weight' => 100,
      ],
      [
        'host' => 'server2',
        'port' => 11211,
        'weight' => 50,
      ],
    ],
  ],
],
登录后复制

然后就可以通过 Yii::$app->cache 访问上面的缓存组件了。

由于所有缓存组件都支持同样的一系列 API ,并不需要修改使用缓存的业务代码就能直接替换为其他底层缓存组件,只需在应用配置中重新配置一下就可以。例如,你可以将上述配置修改为使用 yii\caching\ApcCache:

'components' => [
  'cache' => [
    'class' => 'yii\caching\ApcCache',
  ],
],
登录后复制

Tip: 你可以注册多个缓存组件,很多依赖缓存的类默认调用名为 cache 的组件(例如 yii\web\UrlManager)。
支持的缓存存储器

Yii 支持一系列缓存存储器,概况如下:

  • yii\caching\ApcCache:使用 PHP APC 扩展。这个选项可以认为是集中式应用程序环境中(例如:单一服务器,没有独立的负载均衡器等)最快的缓存方案。
  • yii\caching\DbCache:使用一个数据库的表存储缓存数据。要使用这个缓存,你必须创建一个与 yii\caching\DbCache::cacheTable 对应的表。
  • yii\caching\DummyCache: 仅作为一个缓存占位符,不实现任何真正的缓存功能。这个组件的目的是为了简化那些需要查询缓存有效性的代码。例如,在开发中如果服务器没有实际的缓存支持,用它配置一个缓存组件。一个真正的缓存服务启用后,可以再切换为使用相应的缓存组件。两种条件下你都可以使用同样的代码 Yii::$app->cache->get($key) 尝试从缓存中取回数据而不用担心 Yii::$app->cache 可能是 null。
  • yii\caching\FileCache:使用标准文件存储缓存数据。这个特别适用于缓存大块数据,例如一个整页的内容。
  • yii\caching\MemCache:使用 PHP memcache 和 memcached 扩展。这个选项被看作分布式应用环境中(例如:多台服务器,有负载均衡等)最快的缓存方案。
  • yii\redis\Cache:实现了一个基于 Redis 键值对存储器的缓存组件(需要 redis 2.6.12 及以上版本的支持 )。
  • yii\caching\WinCache:使用 PHP WinCache(另可参考)扩展.
  • yii\caching\XCache:使用 PHP XCache扩展。
  • yii\caching\ZendDataCache:使用 Zend Data Cache 作为底层缓存媒介。
  • Tip: 你可以在同一个应用程序中使用不同的缓存存储器。一个常见的策略是使用基于内存的缓存存储器存储小而常用的数据(例如:统计数据),使用基于文件或数据库的缓存存储器存储大而不太常用的数据(例如:网页内容)。

缓存 API

所有缓存组件都有同样的基类 yii\caching\Cache ,因此都支持如下 API:

  • yii\caching\Cache::get():通过一个指定的键(key)从缓存中取回一项数据。如果该项数据不存在于缓存中或者已经过期/失效,则返回值 false。
  • yii\caching\Cache::set():将一项数据指定一个键,存放到缓存中。
  • yii\caching\Cache::add():如果缓存中未找到该键,则将指定数据存放到缓存中。
  • yii\caching\Cache::mget():通过指定的多个键从缓存中取回多项数据。
  • yii\caching\Cache::mset():将多项数据存储到缓存中,每项数据对应一个键。
  • yii\caching\Cache::madd():将多项数据存储到缓存中,每项数据对应一个键。如果某个键已经存在于缓存中,则该项数据会被跳过。
  • yii\caching\Cache::exists():返回一个值,指明某个键是否存在于缓存中。
  • yii\caching\Cache::delete():通过一个键,删除缓存中对应的值。
  • yii\caching\Cache::flush():删除缓存中的所有数据。
  • 有些缓存存储器如 MemCache,APC 支持以批量模式取回缓存值,这样可以节省取回缓存数据的开支。 yii\caching\Cache::mget() 和 yii\caching\Cache::madd() API提供对该特性的支持。如果底层缓存存储器不支持该特性,Yii 也会模拟实现。

由于 yii\caching\Cache 实现了 PHP ArrayAccess 接口,缓存组件也可以像数组那样使用,下面是几个例子:

$cache['var1'] = $value1; // 等价于: $cache->set('var1', $value1);
$value2 = $cache['var2']; // 等价于: $value2 = $cache->get('var2');
登录后复制

缓存键

存储在缓存中的每项数据都通过键作唯一识别。当你在缓存中存储一项数据时,必须为它指定一个键,稍后从缓存中取回数据时,也需要提供相应的键。

你可以使用一个字符串或者任意值作为一个缓存键。当键不是一个字符串时,它将会自动被序列化为一个字符串。

定义一个缓存键常见的一个策略就是在一个数组中包含所有的决定性因素。例如,yii\db\Schema 使用如下键存储一个数据表的结构信息。

[
  __CLASS__,       // 结构类名
  $this->db->dsn,     // 数据源名称
  $this->db->username,  // 数据库登录用户名
  $name,         // 表名
];
登录后复制

如你所见,该键包含了可唯一指定一个数据库表所需的所有必要信息。

当同一个缓存存储器被用于多个不同的应用时,应该为每个应用指定一个唯一的缓存键前缀以避免缓存键冲突。可以通过配置 yii\caching\Cache::keyPrefix 属性实现。例如,在应用配置中可以编写如下代码:

'components' => [
  'cache' => [
    'class' => 'yii\caching\ApcCache',
    'keyPrefix' => 'myapp',    // 唯一键前缀
  ],
],
登录后复制

为了确保互通性,此处只能使用字母和数字。

缓存过期

默认情况下,缓存中的数据会永久存留,除非它被某些缓存策略强制移除(例如:缓存空间已满,最老的数据会被移除)。要改变此特性,你可以在调用 yii\caching\Cache::set() 存储一项数据时提供一个过期时间参数。该参数代表这项数据在缓存中可保持有效多少秒。当你调用 yii\caching\Cache::get() 取回数据时,如果它已经过了超时时间,该方法将返回 false,表明在缓存中找不到这项数据。例如:

// 将数据在缓存中保留 45 秒
$cache->set($key, $data, 45);

sleep(50);

$data = $cache->get($key);
if ($data === false) {
  // $data 已过期,或者在缓存中找不到
}

登录后复制

缓存依赖

除了超时设置,缓存数据还可能受到缓存依赖的影响而失效。例如,yii\caching\FileDependency 代表对一个文件修改时间的依赖。这个依赖条件发生变化也就意味着相应的文件已经被修改。因此,缓存中任何过期的文件内容都应该被置为失效状态,对 yii\caching\Cache::get() 的调用都应该返回 false。

缓存依赖用 yii\caching\Dependency 的派生类所表示。当调用 yii\caching\Cache::set() 在缓存中存储一项数据时,可以同时传递一个关联的缓存依赖对象。例如:

// 创建一个对 example.txt 文件修改时间的缓存依赖
$dependency = new \yii\caching\FileDependency(['fileName' => 'example.txt']);

// 缓存数据将在30秒后超时
// 如果 example.txt 被修改,它也可能被更早地置为失效状态。
$cache->set($key, $data, 30, $dependency);

// 缓存会检查数据是否已超时。
// 它还会检查关联的依赖是否已变化。
// 符合任何一个条件时都会返回 false。
$data = $cache->get($key);

登录后复制

下面是可用的缓存依赖的概况:

  • yii\caching\ChainedDependency:如果依赖链上任何一个依赖产生变化,则依赖改变。
  • yii\caching\DbDependency:如果指定 SQL 语句的查询结果发生了变化,则依赖改变。
  • yii\caching\ExpressionDependency:如果指定的 PHP 表达式执行结果发生变化,则依赖改变。
  • yii\caching\FileDependency:如果文件的最后修改时间发生变化,则依赖改变。
  • yii\caching\GroupDependency:将一项缓存数据标记到一个组名,你可以通过调用 yii\caching\GroupDependency::invalidate() 一次性将相同组名的缓存全部置为失效状态。

查询缓存

查询缓存是一个建立在数据缓存之上的特殊缓存特性。它用于缓存数据库查询的结果。

查询缓存需要一个 yii\db\Connection 和一个有效的 cache 应用组件。查询缓存的基本用法如下,假设 $db 是一个 yii\db\Connection 实例:

$duration = 60;   // 缓存查询结果60秒
$dependency = ...; // 可选的缓存依赖

$db->beginCache($duration, $dependency);

// ...这儿执行数据库查询...

$db->endCache();

登录后复制

如你所见,beginCache() 和 endCache() 中间的任何查询结果都会被缓存起来。如果缓存中找到了同样查询的结果,则查询会被跳过,直接从缓存中提取结果。

查询缓存可以用于 ActiveRecord 和 DAO。

Info: 有些 DBMS (例如:MySQL)也支持数据库服务器端的查询缓存。你可以选择使用任一查询缓存机制。上文所述的查询缓存的好处在于你可以指定更灵活的缓存依赖因此可能更加高效。
配置

查询缓存有两个通过 yii\db\Connection 设置的配置项:

yii\db\Connection::queryCacheDuration: 查询结果在缓存中的有效期,以秒表示。如果在调用 yii\db\Connection::beginCache() 时传递了一个显式的时值参数,则配置中的有效期时值会被覆盖。
yii\db\Connection::queryCache: 缓存应用组件的 ID。默认为 'cache'。只有在设置了一个有效的缓存应用组件时,查询缓存才会有效。
限制条件

当查询结果中含有资源句柄时,查询缓存无法使用。例如,在有些 DBMS 中使用了 BLOB 列的时候,缓存结果会为该数据列返回一个资源句柄。

有些缓存存储器有大小限制。例如,memcache 限制每条数据最大为 1MB。因此,如果查询结果的大小超出了该限制,则会导致缓存失败。

片段缓存

片段缓存指的是缓存页面内容中的某个片段。例如,一个页面显示了逐年销售额的摘要表格,可以把表格缓存下来,以消除每次请求都要重新生成表格的耗时。片段缓存是基于数据缓存实现的。

在视图中使用以下结构启用片段缓存:

if ($this->beginCache($id)) {

  // ... 在此生成内容 ...

  $this->endCache();
}

登录后复制

调用 yii\base\View::beginCache() 和 yii\base\View::endCache() 方法包裹内容生成逻辑。如果缓存中存在该内容,yii\base\View::beginCache() 方法将渲染内容并返回 false,因此将跳过内容生成逻辑。否则,内容生成逻辑被执行,一直执行到 yii\base\View::endCache() 时,生成的内容将被捕获并存储在缓存中。

和[数据缓存]一样,每个片段缓存也需要全局唯一的 $id 标记。

缓存选项

如果要为片段缓存指定额外配置项,请通过向 yii\base\View::beginCache() 方法第二个参数传递配置数组。在框架内部,该数组将被用来配置一个 yii\widget\FragmentCache 小部件用以实现片段缓存功能。

过期时间(duration)

或许片段缓存中最常用的一个配置选项就是 yii\widgets\FragmentCache::duration 了。它指定了内容被缓存的秒数。以下代码缓存内容最多一小时:

if ($this->beginCache($id, ['duration' => 3600])) {

  // ... 在此生成内容 ...

  $this->endCache();
}

登录后复制

如果该选项未设置,则默认为 0,永不过期。

依赖

和[数据缓存]一样,片段缓存的内容一样可以设置缓存依赖。例如一段被缓存的文章,是否重新缓存取决于它是否被修改过。

通过设置 yii\widgets\FragmentCache::dependency 选项来指定依赖,该选项的值可以是一个 yii\caching\Dependency 类的派生类,也可以是创建缓存对象的配置数组。以下代码指定了一个片段缓存,它依赖于 update_at 字段是否被更改过的。

$dependency = [
  'class' => 'yii\caching\DbDependency',
  'sql' => 'SELECT MAX(updated_at) FROM post',
];

if ($this->beginCache($id, ['dependency' => $dependency])) {

  // ... 在此生成内容 ...

  $this->endCache();
}

登录后复制

变化

缓存的内容可能需要根据一些参数的更改而变化。例如一个 Web 应用支持多语言,同一段视图代码也许需要生成多个语言的内容。因此可以设置缓存根据应用当前语言而变化。

通过设置 yii\widgets\FragmentCache::variations 选项来指定变化,该选项的值应该是一个标量,每个标量代表不同的变化系数。例如设置缓存根据当前语言而变化可以用以下代码:

if ($this->beginCache($id, ['variations' => [Yii::$app->language]])) {

  // ... 在此生成内容 ...

  $this->endCache();
}

登录后复制

开关

有时你可能只想在特定条件下开启片段缓存。例如,一个显示表单的页面,可能只需要在初次请求时缓存表单(通过 GET 请求)。随后请求所显示(通过 POST 请求)的表单不该使用缓存,因为此时表单中可能包含用户输入内容。鉴于此种情况,可以使用 yii\widgets\FragmentCache::enabled 选项来指定缓存开关,如下所示:

if ($this->beginCache($id, ['enabled' => Yii::$app->request->isGet])) {

  // ... 在此生成内容 ...

  $this->endCache();
}

登录后复制

缓存嵌套

片段缓存可以被嵌套使用。一个片段缓存可以被另一个包裹。例如,评论被缓存在里层,同时整个评论的片段又被缓存在外层的文章中。以下代码展示了片段缓存的嵌套使用:

if ($this->beginCache($id1)) {

  // ...在此生成内容...

  if ($this->beginCache($id2, $options2)) {

    // ...在此生成内容...

    $this->endCache();
  }

  // ...在此生成内容...

  $this->endCache();
}

登录后复制

可以为嵌套的缓存设置不同的配置项。例如,内层缓存和外层缓存使用不同的过期时间。甚至当外层缓存的数据过期失效了,内层缓存仍然可能提供有效的片段缓存数据。但是,反之则不然。如果外层片段缓存没有过期而被视为有效,此时即使内层片段缓存已经失效,它也将继续提供同样的缓存副本。因此,你必须谨慎处理缓存嵌套中的过期时间和依赖,否则外层的片段很有可能返回的是不符合你预期的失效数据。

译注:外层的失效时间应该短于内层,外层的依赖条件应该低于内层,以确保最小的片段,返回的是最新的数据。
动态内容

使用片段缓存时,可能会遇到一大段较为静态的内容中有少许动态内容的情况。例如,一个显示着菜单栏和当前用户名的页面头部。还有一种可能是缓存的内容可能包含每次请求都需要执行的 PHP 代码(例如注册资源包的代码)。这两个问题都可以使用动态内容功能解决。

动态内容的意思是这部分输出的内容不该被缓存,即便是它被包裹在片段缓存中。为了使内容保持动态,每次请求都执行 PHP 代码生成,即使这些代码已经被缓存了。

可以在片段缓存中调用 yii\base\View::renderDynamic() 去插入动态内容,如下所示:

if ($this->beginCache($id1)) {

  // ...在此生成内容...

  echo $this->renderDynamic('return Yii::$app->user->identity->name;');

  // ...在此生成内容...

  $this->endCache();
}

登录后复制

yii\base\View::renderDynamic() 方法接受一段 PHP 代码作为参数。代码的返回值被看作是动态内容。这段代码将在每次请求时都执行,无论其外层的片段缓存是否被存储。

您可能感兴趣的文章:

  • 详解PHP的Yii框架中自带的前端资源包的使用
  • 简介PHP的Yii框架中缓存的一些高级用法
  • PHP的Yii框架中View视图的使用进阶
  • PHP的Yii框架中创建视图和渲染视图的方法详解
  • PHP的Yii框架中Model模型的学习教程
  • 详解PHP的Yii框架中的Controller控制器
  • PHP的Yii框架中移除组件所绑定的行为的方法
  • PHP的Yii框架中行为的定义与绑定方法讲解
  • 深入讲解PHP的Yii框架中的属性(Property)
  • 详解PHP的Yii框架中扩展的安装与使用
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
威尔R.E.P.O.有交叉游戏吗?
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

视频文件存储在浏览器缓存中的位置在哪里? 视频文件存储在浏览器缓存中的位置在哪里? Feb 19, 2024 pm 05:09 PM

浏览器缓存视频在哪个文件夹在日常使用互联网浏览器时,我们经常会观看各种在线视频,比如在YouTube上看音乐视频或在Netflix上观看电影等。而这些视频在加载过程中会被浏览器缓存下来,以便日后再次播放时能够快速加载。那么问题来了,这些缓存的视频实际上存储在哪个文件夹中呢?不同浏览器的缓存视频文件夹保存位置是不同的。下面我们将分别介绍几种常见的浏览器以及它们

Linux如何查看和刷新dns缓存 Linux如何查看和刷新dns缓存 Mar 07, 2024 am 08:43 AM

DNS(DomainNameSystem)是互联网中用于将域名转换为对应IP地址的系统。在Linux系统中,DNS缓存是一种将域名和IP地址的映射关系存储在本地的机制,可提高域名解析速度,减轻DNS服务器的负担。DNS缓存允许系统在之后访问相同域名时快速检索IP地址,而不必每次都向DNS服务器发出查询请求,从而提高网络性能和效率。本文不念将和大家一起探讨如何在Linux上查看和刷新DNS缓存,以及相关的详细内容和示例代码。DNS缓存的重要性在Linux系统中,DNS缓存扮演着关键的角色。它的存在

加速你的应用程序:Guava缓存的简易指南 加速你的应用程序:Guava缓存的简易指南 Jan 31, 2024 pm 09:11 PM

Guava缓存入门指南:加速你的应用程序Guava缓存是一个高性能的内存缓存库,它可以显着提高应用程序的性能。它提供了多种缓存策略,包括LRU(最近最少使用)、LFU(最近最不经常使用)和TTL(生存时间)。 1.安装Guava缓存在你的项目中添加Guava缓存库的依赖。 com.goog

会对 HTML 文件进行缓存吗 会对 HTML 文件进行缓存吗 Feb 19, 2024 pm 01:51 PM

标题:HTML文件的缓存机制及代码示例导语:在编写网页时,我们经常会遇到浏览器缓存的问题。本文将详细介绍HTML文件的缓存机制,并提供一些具体的代码示例,以帮助读者更好理解和应用这一机制。一、浏览器缓存原理在浏览器中,每当访问一个网页时,浏览器会先检查缓存中是否有该网页的副本。如果有,则直接从缓存获取网页内容,这就是浏览器缓存的基本原理。浏览器缓存机制的好处

PHP APCu 的高级用法:解锁隐藏的力量 PHP APCu 的高级用法:解锁隐藏的力量 Mar 01, 2024 pm 09:10 PM

PHPAPCu(替代php缓存)是一个加速PHP应用程序的opcode缓存和数据缓存模块。理解其高级功能对于充分利用其潜力至关重要。1.批量操作:APCu提供批量操作方法,可同时处理大量键值对。这对于大规模缓存清除或更新非常有用。//批量获取缓存键$values=apcu_fetch(["key1","key2","key3"]);//批量清除缓存键apcu_delete(["key1","key2","key3"]);2.设置缓存过期时间:APCu允许您为缓存项设置过期时间,以便在指定时间后自

如何将浏览器缓存中的视频文件保存到本地 如何将浏览器缓存中的视频文件保存到本地 Feb 23, 2024 pm 06:45 PM

浏览器缓存的视频怎么导出来随着互联网的快速发展,视频已经成为人们日常生活中不可或缺的一部分。而在浏览网页时,我们常常会遇到想要保存或分享的视频内容,但是有时候我们却无法找到视频文件的来源,因为它们可能只存在于浏览器的缓存中。那么,如何导出浏览器缓存中的视频呢?本文将为您介绍几种常用的方法。首先,我们需要明确一个概念,即浏览器缓存。浏览器缓存是浏览器为了提高用

PHP开发中的缓存机制与应用实战 PHP开发中的缓存机制与应用实战 May 09, 2024 pm 01:30 PM

在PHP开发中,缓存机制通过将经常访问的数据临时存储在内存或磁盘中来提升性能,从而减少数据库访问次数。缓存类型主要包括内存、文件和数据库缓存。PHP中可以使用内置函数或第三方库实现缓存,如cache_get()和Memcache。常见的实战应用包括缓存数据库查询结果以优化查询性能,以及缓存页面输出以加快渲染速度。缓存机制有效改善网站响应速度,提升用户体验并降低服务器负载。

深入研究PHP缓存技术:加速网站性能的关键 深入研究PHP缓存技术:加速网站性能的关键 Jan 23, 2024 am 08:37 AM

PHP缓存技术探索:提升网站性能的利器,需要具体代码示例引言:在当今互联网的高速发展下,网站性能对于用户体验和搜索引擎排名至关重要。而PHP作为一种常用的编程语言于网站开发中广泛应用,如何提升PHP网站的性能成为了开发者们迫切探索的问题。其中一个非常重要的解决方案就是利用PHP缓存技术,本文将对PHP缓存的概念和具体技术进行探索,并附带代码示例,帮助读者理解

See all articles