之前我已经简单的记录过在Yii中的缓存使用,这里我来详细的介绍下在Yii中的缓存使用

在yii中缓存一共分为四种,分别为数据缓存,片段缓存,页面缓存,HTTP缓存

在Yii中使用缓存之前,首先在配置文件main.php文件中配置缓存组件

一:缓存组件配置

'components' => [
'cache' => [
        'class' => 'yii\caching\FileCache',
        //缓存目录
        'cachePath' => '@common/runtime'
    ],
]

在Yii中有多种缓存方式,上面的是文件存储缓存,常见一共有三种,除了上面的文件存储类缓存之外,还有使用php的APC拓展缓存和使用数据库存储缓存

使用php的APC拓展缓存配置:

'components' => [
'cache' => [
        'class' => 'yii\caching\ApcCache',
    ],
]

使用数据库存储缓存配置:

'components' => [
'cache' => [
        'class' => 'yii\caching\DbCache',
    ],
]

如果使用数据库存储缓存的话,这时候需要在数据库中创建一个缓存表cache,在这里我们可以使用Yii自带的migrations工具生成缓存表,migrations使用方式参考: https://www.wj0511.com/site/detail.html?id=294

生成缓存表的migrate:

/**
 * {@inheritdoc}
 */
public function safeUp()
{
    $this->createTable('{{%cache}}', [
        'id' => $this->char(128)->defaultValue('')->comment('缓存ID'),
        'expire' => $this->integer()->defaultValue(0)->comment('到期时间'),
        'data' => $this->getDb()->getSchema()->createColumnSchemaBuilder('blob')->comment('缓存数据'),
        'PRIMARY KEY ([[id]], [[expire]])',
    ], 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB COMMENT=\'缓存表\'');
}
/**
 * {@inheritdoc}
 */
public function safeDown()
{
    $this->dropTable('{{%cache}}');
}

这里注意:由于data字段是blob类型,yii框架没有生成blob类型的方法,你需要自己进行设置blob类型

$this->getDb()->getSchema()->createColumnSchemaBuilder('字段类型')

二:数据缓存

数据缓存是指将一些 PHP 变量存储到缓存中,使用时再从缓存中取回

1:数据缓存的获取和设置

在Yii中使用数据缓存如下:

$cache = Yii::$app->cache;
$key = 'key';//缓存ID
$data = $cache->get($key);
if ($data === false) {
    $data = '需要缓存的数据';
    // 将 $data 存放到缓存供下次使用
    $cache->set($key, $data);
}

如上代码表示:首先判断缓存数据中是否有缓存ID为key的缓存数据,如果有直接获取缓存中的数据,如果没有则执行set方法将数据加入到缓存中,并返回缓存数据

将数据加入到缓存中的set方法一共有四个参数,语法结构如下

$cache->set($key, $value, $duration = null, $dependency = null);

参数说明:

key:缓存ID,为必填项

value:需要缓存的数据,为必填项

duration:缓存过期时间参数,该参数表示缓存数据可保持的有效时间(单位为秒),为非必填项

dependency:缓存依赖参数,如当一个缓存数据的缓存依赖信息发生了变化之后,这时候缓存数据就会被设为失效,及过期

如:

$cache = Yii::$app->cache;
// 创建一个对 test.txt文件修改时间的缓存依赖
$dependency = new \yii\caching\FileDependency(['fileName' => 'test.txt']);
$cache->set($key, $data, null, $dependency);

如上设置了一个缓存数据,当test.txt文件被修改的话,这时候的缓存数据就会被设为失效,及过期

常见的缓存依赖可以参考Yii框架的官网,这里不进行过多的叙述了

2:清除缓存

既然有设置缓存,那么一定有清除缓存

(1)清除指定缓存ID的缓存数据

$cache = Yii::$app->cache;
$cache->delete($key);

(2)清除所有缓存数据

$cache = Yii::$app->cache;
$cache->flush();

3:查询缓存

有时候我们在查询数据库的数据时,此数据基本上很长数据都不会发生变化,这时候我们就可以使用查询缓存来缓存数据库的查询结果提高效率

查询缓存两种方式:使用yiidbConnection实例来实现查询缓存和使用模型实现查询缓存

(1)使用yiidbConnection实例来实现查询缓存

$db = Yii::$app->db;
$result = $db->cache(function ($db) {
    // SQL查询的结果将从缓存中提供
    // 如果启用查询缓存并且在缓存中找到查询结果
    return $db->createCommand('SELECT * FROM yii_user WHERE id=1')->queryOne();
});

如上将SELECT * FROM yii_user WHERE id=1的结果进行缓存

(2):使用模型实现查询缓存

$result = User::getDb()->cache(function ($db) {
   return User::findOne(1); 
});

如上将User::findOne(1)查询的结果进行缓存

上面的cache方法一共有三个参数

cache(callable $callable, $duration = null, $dependency = null)

参数说明:

callable:匿名函数,需要缓存的sql查询数据

duration,dependency参数可查看上面的说明

三:片段缓存

片段缓存指的是缓存页面内容中的某个片段,如:在html中,你想要将一段html片段缓存起来,避免每次请求都重新生成此段html片段,这时候就可以使用片段缓存

实例:

<?php if ($this->beginCache('key')):?>  
    <span>html片段</span>
<?php
    $this->endCache();
    endif;
?>

如上就将<span>html片段</span>片段进行了缓存

beginCache方法参数说明:

beginCache($id, $properties = [])

$id:缓存Id

$properties:缓存配置数组,缓存数组中常见的配置参数有:duration(缓存过期事件,单位为秒),dependency(缓存依赖),enabled(开关,默认为true,表示开启缓存,false为关闭缓存)

如:

$dependency = [
    'class' => 'yii\caching\DbDependency',
    'sql' => 'SELECT MAX(updated_time) FROM user',
];
if ($this->beginCache('key',[
    'duration' => 3600,//设置缓存过期时间为3600秒,
    'dependency' => $dependency,//设置缓存依赖,当user表中的update_time字段值发生变化,缓存失效,重新进行缓存
    'enabled' => Yii::$app->request->isGet,//当为get请求开启缓存,非get请求则关闭缓存
])) {
    // ... 在此生成内容 ...
    $this->endCache();
}

四:页面缓存

页面缓存指的是在服务器端缓存整个页面的内容。 随后当同一个页面被请求时,内容将从缓存中取出,而不是重新生成

页面缓存由 yiifiltersPageCache 类提供支持,这个类是一个过滤器,所以如果你需要使用页面缓存,只需要在控制器的behaviors方法中引入yiifiltersPageCache类即可

如:

public function behaviors()
{
    return [
        [
            'class' => 'yii\filters\PageCache',
            //只有在执行page操作时启用缓存
            'only' => ['page'],
            //缓存过期时间为60秒
            'duration' => 60,
            //当user表中的数据总数发生变化时页面缓存失效,重新进行缓存
            'dependency' => [
                'class' => 'yii\caching\DbDependency',
                'sql' => 'SELECT COUNT(*) FROM user',
            ],
        ],
    ];
}

五:HTTP缓存

前面讲到的缓存都是服务端缓存,在Yii中还可以使用客户端缓存去节省相同页面内容的生成和传输时间,及HTTP缓存

HTTP缓存使用到了yiifiltersHttpCache类,这个类也是一个过滤器,所以你要使用HTTP缓存,及在控制器的behaviors方法中引入yiifiltersHttpCache类

HTTP缓存可以设置与缓存有关的HTTP头

1:Last-Modified 头

通过配置yiifiltersHttpCache::$lastModified属性向客户端发送Last-Modified 头

如:

public function behaviors()
{
    return [
        [
            'class' => 'yii\filters\HttpCache',
            //只有在执行index操作时启用HTTP缓存
            'only' => ['page'],
            //基于页面最后修改时间生成一个Last-Modified的HTTP头,当user数据发生变化,HTTP缓存失效,重新生成缓存
            'lastModified' => function ($action, $params) {
                $query = new \yii\db\Query();
                return $query->from('user')->max('updated_time');
            },
        ]
    ];
}

2:ETag 头

ETag使用一个哈希值表示页面内容。如果页面被修改过, 哈希值也会随之改变。通过对比客户端的哈希值和服务器端生成的哈希值, 浏览器就能判断页面是否被修改过,进而决定是否应该重新传输内容,通过配置 yiifiltersHttpCache::$etagSeed 属性向客户端发送 ETag 头

如:

public function behaviors()
{
    return [
        [
            'class' => 'yii\filters\HttpCache',
            //只有在执行view操作时启用HTTP缓存
            'only' => ['view'],
            //基于用户请求的username和password生成一个 ETag的HTTP头,当username和password数据被修改的话,缓存失效,重新生成缓存
            'etagSeed' => function ($action, $params) {
                $user = User::findOne(\Yii::$app->request->get('id'));
                return serialize([$user->username, $user->password]);
            },
        ]
    ];
}

huaweichenai
695 声望115 粉丝