搜索
首页后端开发php教程深入解析PHP的Yii框架中的缓存功能,yii框架_PHP教程

深入解析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框架中扩展的安装与使用

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1117069.htmlTechArticle深入解析PHP的Yii框架中的缓存功能,yii框架 数据缓存是指将一些 PHP 变量存储到缓存中,使用时再从缓存中取回。它也是更高级缓存特性的...
声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
PHP行动:现实世界中的示例和应用程序PHP行动:现实世界中的示例和应用程序Apr 14, 2025 am 12:19 AM

PHP在电子商务、内容管理系统和API开发中广泛应用。1)电子商务:用于购物车功能和支付处理。2)内容管理系统:用于动态内容生成和用户管理。3)API开发:用于RESTfulAPI开发和API安全性。通过性能优化和最佳实践,PHP应用的效率和可维护性得以提升。

PHP:轻松创建交互式Web内容PHP:轻松创建交互式Web内容Apr 14, 2025 am 12:15 AM

PHP可以轻松创建互动网页内容。1)通过嵌入HTML动态生成内容,根据用户输入或数据库数据实时展示。2)处理表单提交并生成动态输出,确保使用htmlspecialchars防XSS。3)结合MySQL创建用户注册系统,使用password_hash和预处理语句增强安全性。掌握这些技巧将提升Web开发效率。

PHP和Python:比较两种流行的编程语言PHP和Python:比较两种流行的编程语言Apr 14, 2025 am 12:13 AM

PHP和Python各有优势,选择依据项目需求。1.PHP适合web开发,尤其快速开发和维护网站。2.Python适用于数据科学、机器学习和人工智能,语法简洁,适合初学者。

PHP的持久相关性:它还活着吗?PHP的持久相关性:它还活着吗?Apr 14, 2025 am 12:12 AM

PHP仍然具有活力,其在现代编程领域中依然占据重要地位。1)PHP的简单易学和强大社区支持使其在Web开发中广泛应用;2)其灵活性和稳定性使其在处理Web表单、数据库操作和文件处理等方面表现出色;3)PHP不断进化和优化,适用于初学者和经验丰富的开发者。

PHP的当前状态:查看网络开发趋势PHP的当前状态:查看网络开发趋势Apr 13, 2025 am 12:20 AM

PHP在现代Web开发中仍然重要,尤其在内容管理和电子商务平台。1)PHP拥有丰富的生态系统和强大框架支持,如Laravel和Symfony。2)性能优化可通过OPcache和Nginx实现。3)PHP8.0引入JIT编译器,提升性能。4)云原生应用通过Docker和Kubernetes部署,提高灵活性和可扩展性。

PHP与其他语言:比较PHP与其他语言:比较Apr 13, 2025 am 12:19 AM

PHP适合web开发,特别是在快速开发和处理动态内容方面表现出色,但不擅长数据科学和企业级应用。与Python相比,PHP在web开发中更具优势,但在数据科学领域不如Python;与Java相比,PHP在企业级应用中表现较差,但在web开发中更灵活;与JavaScript相比,PHP在后端开发中更简洁,但在前端开发中不如JavaScript。

PHP与Python:核心功能PHP与Python:核心功能Apr 13, 2025 am 12:16 AM

PHP和Python各有优势,适合不同场景。1.PHP适用于web开发,提供内置web服务器和丰富函数库。2.Python适合数据科学和机器学习,语法简洁且有强大标准库。选择时应根据项目需求决定。

PHP:网络开发的关键语言PHP:网络开发的关键语言Apr 13, 2025 am 12:08 AM

PHP是一种广泛应用于服务器端的脚本语言,特别适合web开发。1.PHP可以嵌入HTML,处理HTTP请求和响应,支持多种数据库。2.PHP用于生成动态网页内容,处理表单数据,访问数据库等,具有强大的社区支持和开源资源。3.PHP是解释型语言,执行过程包括词法分析、语法分析、编译和执行。4.PHP可以与MySQL结合用于用户注册系统等高级应用。5.调试PHP时,可使用error_reporting()和var_dump()等函数。6.优化PHP代码可通过缓存机制、优化数据库查询和使用内置函数。7

See all articles

热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.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
1 个月前By尊渡假赌尊渡假赌尊渡假赌

热工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

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