>  기사  >  php教程  >  YII 프레임워크 프레임워크 튜토리얼의 캐시 사용에 대한 자세한 설명

YII 프레임워크 프레임워크 튜토리얼의 캐시 사용에 대한 자세한 설명

高洛峰
高洛峰원래의
2016-12-27 14:04:301363검색

이 문서의 예에서는 YII 프레임워크 프레임워크 캐시의 사용법을 설명합니다. 참고할 수 있도록 모든 사람과 공유하세요. 자세한 내용은 다음과 같습니다.

캐싱하는 이유는 잘 알려져 있습니다. 따라서 효율적이고 사용하기 쉬운 프레임워크인 YII는 캐싱을 지원할 수밖에 없습니다. 따라서 YII는 널리 사용되는 다양한 캐시에 대한 인터페이스를 제공하며 필요에 따라 다양한 캐시를 사용할 수 있습니다.

1. YII 캐싱 소개

YII의 캐시는 특히 다음 디렉터리

/yii_dev/yii/framework/caching# 트리에서 구성 요소를 통해 정의됩니다. 🎜>.
├── CApcCache.php
├── CCache.php
├── CDbCache.php
├── CDummyCache.php
├── CEAcceleratorCache.php
├── CFileCache.php
├── CMemCache.php
├── CWinCache.php 종속성
├── CXCache.php
├── CZendDataCache.php
└──
├── CCacheDependency.php
├── CChainedCacheDependency.php
├── CDbCacheDependency.php
├── CDirectoryCacheDependency.php
├── CExpression ency.php
├ ── CFileCacheDependency.php
└── CGlobalStateCacheDependency.php

디렉토리 1개, 파일 17개

공식 원문 설명은 다음과 같습니다.

Yii는 다양한 캐싱을 제공합니다. 캐시 데이터는 다른 미디어에 저장될 수 있습니다. 예를 들어 CMemCache 구성 요소는 PHP의 memcache 확장을 캡슐화하고 메모리를 캐시 저장 매체로 사용합니다. CApcCache 구성 요소는 PHP APC 확장을 캡슐화하고 CDbCache 구성 요소는 캐시된 데이터를 데이터베이스에 저장합니다. 사용 가능한 캐싱 구성 요소 목록은 다음과 같습니다.

CMemCache: PHP memcache 확장을 사용합니다.

CApcCache: PHP APC 확장을 사용합니다.

CXCache: PHP XCache 확장을 사용합니다. . 이는 버전 1.0.1부터 지원됩니다.

CEAcceleratorCache: PHP EAccelerator 확장을 사용합니다.

CDbCache: 데이터 테이블을 사용하여 캐시 데이터를 저장합니다. 기본적으로 런타임 디렉터리에 SQLite3 데이터베이스를 생성하고 사용합니다. ConnectionID 속성을 설정하여 사용할 데이터베이스를 지정할 수도 있습니다.

CZendDataCache: Zend 데이터 캐시를 백엔드 캐싱 매체로 사용합니다. 이는 버전 1.0.4부터 지원됩니다.

CFileCache: 파일을 사용하여 캐시 데이터를 저장합니다. 이는 대량의 데이터(예: 페이지)를 저장하는 데 특히 유용합니다. 이는 버전 1.0.6부터 지원됩니다.

CDummyCache: 현재 더미 캐시는 캐싱 기능을 구현하지 않습니다. 이 구성 요소의 목적은 캐시 가용성을 확인해야 하는 코드를 단순화하는 것입니다. 예를 들어 개발 단계에서 또는 서버가 아직 실제 캐싱 기능을 지원하지 않는 경우 이 캐싱 구성 요소를 사용할 수 있습니다. 실제 캐싱 지원이 활성화되면 해당 캐싱 구성 요소를 사용하도록 전환할 수 있습니다. 두 경우 모두 Yii::app()->cache가 null일 수 있다는 걱정 없이 동일한 코드 Yii::app()->cache->get($key)를 사용하여 데이터 조각을 가져올 수 있습니다. 이 구성 요소는 버전 1.0.5부터 지원됩니다.

팁: 이러한 모든 캐싱 구성 요소는 동일한 기본 클래스 CCache에서 상속되므로 캐시를 사용하는 코드를 변경하지 않고도 다른 캐싱 방법으로 전환할 수 있습니다.

캐싱은 다양한 수준에서 사용될 수 있습니다. 가장 낮은 수준에서는 캐시를 사용하여 변수와 같은 개별 데이터를 저장합니다. 다음 단계에서는 보기 스크립트의 일부로 생성된 페이지 조각을 캐시에 저장합니다. 그리고 가장 높은 수준에서는 전체 페이지를 캐시에 저장하고 필요할 때 검색합니다.

다음 몇 섹션에서는 이러한 수준에서 캐싱을 사용하는 방법을 자세히 설명합니다.

참고: 정의에 따르면 캐시는 불안정한 저장 매체입니다. 시간 초과가 없더라도 캐시된 데이터가 존재하는지 보장하지 않습니다. 따라서 캐시를 영구 저장소로 사용하지 마십시오. (예를 들어 세션 데이터를 저장하는 데 캐시를 사용하지 마십시오.)

2. 캐시 구성 및 호출 방법

Yii의 캐시는 주로 컴포넌트를 통해 구현되며, 구체적인 구성 방법은 캐시 클래스 설명을 통해 구성할 수 있습니다.

일반적으로 캐시 구성요소를 지정하는 클래스

예: apc

'cache'=>array(
  'class'=>'system.caching.CApcCache'
),
memcache의 구성 방법은

* array(
*   'components'=>array(
*     'cache'=>array(
*       'class'=>'CMemCache',
*       'servers'=>array(
*         array(
*           'host'=>'server1',
*           'port'=>11211,
*           'weight'=>60,
*         ),
*         array(
*           'host'=>'server2',
*           'port'=>11211,
*           'weight'=>40,
*         ),
*       ),
*     ),
*   ),
* )
일 수 있습니다. :

yii는 주로 CCache에 초점을 맞춰 다양한 캐시 작업에 대한 메서드를 캡슐화합니다. CCache는 모든 캐시 클래스의 기본 클래스입니다. 따라서 캐시를 구성한 후 호출 방법은 매우 간단합니다.

<?php
/**
 * CCache is the base class for cache classes with different cache storage implementation.
 *
 * A data item can be stored in cache by calling {@link set} and be retrieved back
 * later by {@link get}. In both operations, a key identifying the data item is required.
 * An expiration time and/or a dependency can also be specified when calling {@link set}.
 * If the data item expires or the dependency changes, calling {@link get} will not
 * return back the data item.
 *
 * Note, by definition, cache does not ensure the existence of a value
 * even if it does not expire. Cache is not meant to be a persistent storage.
 *
 * CCache implements the interface {@link ICache} with the following methods:
 * <ul>
 * <li>{@link get} : retrieve the value with a key (if any) from cache</li>
 * <li>{@link set} : store the value with a key into cache</li>
 * <li>{@link add} : store the value only if cache does not have this key</li>
 * <li>{@link delete} : delete the value with the specified key from cache</li>
 * <li>{@link flush} : delete all values from cache</li>
 * </ul>
 *
 * Child classes must implement the following methods:
 * <ul>
 * <li>{@link getValue}</li>
 * <li>{@link setValue}</li>
 * <li>{@link addValue}</li>
 * <li>{@link deleteValue}</li>
 * <li>{@link flush} (optional)</li>
 * </ul>
 *
 * CCache also implements ArrayAccess so that it can be used like an array.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @version $Id: CCache.php 3001 2011-02-24 16:42:44Z alexander.makarow $
 * @package system.caching
 * @since 1.0
 */
abstract class CCache extends CApplicationComponent implements ICache, ArrayAccess
{
CCache 클래스 설명에 따르면 일반적인 캐시 작업 방법은 get, set, add, delete, flash임을 알 수 있습니다.

/**
 * Retrieves a value from cache with a specified key.
 * @param string $id a key identifying the cached value
 * @return mixed the value stored in cache, false if the value is not in the cache, expired or the dependency has changed.
 */
public function get($id)
{
  if(($value=$this->getValue($this->generateUniqueKey($id)))!==false)
  {
    $data=unserialize($value);
    if(!is_array($data))
      return false;
    if(!($data[1] instanceof ICacheDependency) || !$data[1]->getHasChanged())
    {
      Yii::trace(&#39;Serving "&#39;.$id.&#39;" from cache&#39;,&#39;system.caching.&#39;.get_class($this));
      return $data[0];
    }
  }
  return false;
}
/**
 * Retrieves multiple values from cache with the specified keys.
 * Some caches (such as memcache, apc) allow retrieving multiple cached values at one time,
 * which may improve the performance since it reduces the communication cost.
 * In case a cache doesn&#39;t support this feature natively, it will be simulated by this method.
 * @param array $ids list of keys identifying the cached values
 * @return array list of cached values corresponding to the specified keys. The array
 * is returned in terms of (key,value) pairs.
 * If a value is not cached or expired, the corresponding array value will be false.
 * @since 1.0.8
 */
public function mget($ids)
{
  $uniqueIDs=array();
  $results=array();
  foreach($ids as $id)
  {
    $uniqueIDs[$id]=$this->generateUniqueKey($id);
    $results[$id]=false;
  }
  $values=$this->getValues($uniqueIDs);
  foreach($uniqueIDs as $id=>$uniqueID)
  {
    if(!isset($values[$uniqueID]))
      continue;
    $data=unserialize($values[$uniqueID]);
    if(is_array($data) && (!($data[1] instanceof ICacheDependency) || !$data[1]->getHasChanged()))
    {
      Yii::trace(&#39;Serving "&#39;.$id.&#39;" from cache&#39;,&#39;system.caching.&#39;.get_class($this));
      $results[$id]=$data[0];
    }
  }
  return $results;
}
/**
 * Stores a value identified by a key into cache.
 * If the cache already contains such a key, the existing value and
 * expiration time will be replaced with the new ones.
 *
 * @param string $id the key identifying the value to be cached
 * @param mixed $value the value to be cached
 * @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
 * @param ICacheDependency $dependency dependency of the cached item. If the dependency changes, the item is labeled invalid.
 * @return boolean true if the value is successfully stored into cache, false otherwise
 */
public function set($id,$value,$expire=0,$dependency=null)
{
  Yii::trace(&#39;Saving "&#39;.$id.&#39;" to cache&#39;,&#39;system.caching.&#39;.get_class($this));
  if($dependency!==null)
    $dependency->evaluateDependency();
  $data=array($value,$dependency);
  return $this->setValue($this->generateUniqueKey($id),serialize($data),$expire);
}
/**
 * Stores a value identified by a key into cache if the cache does not contain this key.
 * Nothing will be done if the cache already contains the key.
 * @param string $id the key identifying the value to be cached
 * @param mixed $value the value to be cached
 * @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
 * @param ICacheDependency $dependency dependency of the cached item. If the dependency changes, the item is labeled invalid.
 * @return boolean true if the value is successfully stored into cache, false otherwise
 */
public function add($id,$value,$expire=0,$dependency=null)
{
  Yii::trace(&#39;Adding "&#39;.$id.&#39;" to cache&#39;,&#39;system.caching.&#39;.get_class($this));
  if($dependency!==null)
    $dependency->evaluateDependency();
  $data=array($value,$dependency);
  return $this->addValue($this->generateUniqueKey($id),serialize($data),$expire);
}
/**
 * Deletes a value with the specified key from cache
 * @param string $id the key of the value to be deleted
 * @return boolean if no error happens during deletion
 */
public function delete($id)
{
  Yii::trace(&#39;Deleting "&#39;.$id.&#39;" from cache&#39;,&#39;system.caching.&#39;.get_class($this));
  return $this->deleteValue($this->generateUniqueKey($id));
}
/**
 * Deletes all values from cache.
 * Be careful of performing this operation if the cache is shared by multiple applications.
 * @return boolean whether the flush operation was successful.
 */
public function flush()
{
  Yii::trace(&#39;Flushing cache&#39;,&#39;system.caching.&#39;.get_class($this));
  return $this->flushValues();
}
즉,

Yii::app()->cache->xxx
xxx는 특정 방법에 해당합니다.

예:

$id = &#39;key1&#39;;
$value = &#39;cache value&#39;;
Yii::app()->cache->add($id, $value);
var_dump(Yii::app()->cache->get($id));
다음은 Yii에서 공식적으로 제공하는 여러 캐싱 방법을 사용하는 방법을 구분하지 않고 여기에 복사합니다.

3. 캐시: 데이터 캐시

데이터 캐시

데이터 캐시는 일부 PHP 변수를 캐시에 저장한 다음 나중에 캐시에서 검색합니다. 이를 위해 구성 요소 캐싱을 위한 기본 클래스 CCache는 가장 일반적으로 사용되는 두 가지 메서드인 set() 및 get()을 제공합니다.

변수 $value를 캐시에 저장하려면 고유 ID를 선택하고 set()을 호출하여 이를 저장합니다.

Yii::app()->cache->set($id, $value);

缓存的数据将一直留在缓存中,除非它由于某些缓存策略(例如缓存空间已满,旧的数据被删除)而被清除。 要改变这种行为,我们可以在调用 set() 的同时提供一个过期参数,这样在设定的时间段之后,缓存数据将被清除:

// 值$value 在缓存中最多保留30秒
Yii::app()->cache->set($id, $value, 30);

稍后当我们需要访问此变量时(在同一个或不同的 Web 请求中),就可以通过 ID 调用 get() 从缓存中将其取回。 如果返回的是 false,表示此值在缓存中不可用,我们应该重新生成它。

$value=Yii::app()->cache->get($id);
if($value===false)
{
  // 因为在缓存中没找到 $value ,重新生成它 ,
  // 并将它存入缓存以备以后使用:
  // Yii::app()->cache->set($id,$value);
}

为要存入缓存的变量选择 ID 时,要确保此 ID 对应用中所有其他存入缓存的变量是唯一的。 而在不同的应用之间,这个 ID 不需要是唯一的。缓存组件具有足够的智慧区分不同应用中的 ID。

一些缓存存储器,例如 MemCache, APC, 支持以批量模式获取多个缓存值。这可以减少获取缓存数据时带来的开销。 从版本 1.0.8 起,Yii 提供了一个新的名为 mget() 的方法。它可以利用此功能。如果底层缓存存储器不支持此功能,mget() 依然可以模拟实现它。

要从缓存中清除一个缓存值,调用 delete(); 要清楚缓存中的所有数据,调用 flush()。 当调用 flush() 时一定要小心,因为它会同时清除其他应用中的缓存。

提示: 由于 CCache 实现了 ArrayAccess,缓存组件也可以像一个数组一样使用。下面是几个例子:

$cache=Yii::app()->cache;
$cache[&#39;var1&#39;]=$value1; // 相当于: $cache->set(&#39;var1&#39;,$value1);
$value2=$cache[&#39;var2&#39;]; // 相当于: $value2=$cache->get(&#39;var2&#39;);

1. 缓存依赖

除了过期设置,缓存数据也可能会因为依赖条件发生变化而失效。例如,如果我们缓存了某些文件的内容,而这些文件发生了改变,我们就应该让缓存的数据失效, 并从文件中读取最新内容而不是从缓存中读取。

我们将一个依赖关系表现为一个 CCacheDependency 或其子类的实例。 当调用 set() 时,我们连同要缓存的数据将其一同传入。

// 此值将在30秒后失效
// 也可能因依赖的文件发生了变化而更快失效
Yii::app()->cache->set($id, $value, 30, new CFileCacheDependency(&#39;FileName&#39;));

现在如果我们通过调用get() 从缓存中获取 $value ,依赖关系将被检查,如果发生改变,我们将会得到一个 false 值,表示数据需要被重新生成。

如下是可用的缓存依赖的简要说明:

CFileCacheDependency: 如果文件的最后修改时间发生改变,则依赖改变。
CDirectoryCacheDependency: 如果目录和其子目录中的文件发生改变,则依赖改变。
CDbCacheDependency: 如果指定 SQL 语句的查询结果发生改变,则依赖改变。
CGlobalStateCacheDependency: 如果指定的全局状态发生改变,则依赖改变。全局状态是应用中的一个跨请求,跨会话的变量。它是通过 CApplication::setGlobalState() 定义的。
CChainedCacheDependency: 如果链中的任何依赖发生改变,则此依赖改变。
CExpressionDependency: 如果指定的 PHP 表达式的结果发生改变,则依赖改变。此类从版本 1.0.4 起可用。

4.缓存的使用:片段缓存

片段缓存(Fragment Caching)

片段缓存指缓存网页某片段。例如,如果一个页面在表中显示每年的销售摘要,我们可以存储此表在缓存中,减少每次请求需要重新产生的时间。

要使用片段缓存,在控制器视图脚本中调用CController::beginCache() 和CController::endCache() 。这两种方法开始和结束包括的页面内容将被缓存。类似data caching ,我们需要一个编号,识别被缓存的片段。

...别的HTML内容...
<?php if($this->beginCache($id)) { ?>
...被缓存的内容...
<?php $this->endCache(); } ?>
...别的HTML内容...

如果我们不设定期限,它将默认为60 ,这意味着60秒后缓存内容将无效。

依赖(Dependency)

像data caching ,内容片段被缓存也可以有依赖。例如,文章的内容被显示取决于文章是否被修改。

要指定一个依赖,我们建立了dependency选项,可以是一个实现[ICacheDependency]的对象或可用于生成依赖对象的配置数组。下面的代码指定片段内容取决于lastModified 列的值是否变化:

...其他HTML内容...
<?php if($this->beginCache($id, array(&#39;dependency&#39;=>array(
    &#39;class&#39;=>&#39;system.caching.dependencies.CDbCacheDependency&#39;,
    &#39;sql&#39;=>&#39;SELECT MAX(lastModified) FROM Post&#39;)))) { ?>
...被缓存的内容...
<?php $this->endCache(); } ?>
...其他HTML内容...

变化(Variation)

缓存的内容可根据一些参数变化。例如,每个人的档案都不一样。缓存的档案内容将根据每个人ID变化。这意味着,当调用beginCache()时将用不同的ID。

COutputCache内置了这一特征,程序员不需要编写根据ID变动内容的模式。以下是摘要。

varyByRoute: 设置此选项为true ,缓存的内容将根据route变化。因此,每个控制器和行动的组合将有一个单独的缓存内容。
varyBySession: 设置此选项为true ,缓存的内容将根据session ID变化。因此,每个用户会话可能会看到由缓存提供的不同内容。
varyByParam: 设置此选项的数组里的名字,缓存的内容将根据GET参数的值变动。例如,如果一个页面显示文章的内容根据id的GET参数,我们可以指定varyByParam为array('id'),以使我们能够缓存每篇文章内容。如果没有这样的变化,我们只能能够缓存某一文章。

varyByExpression: by setting this option to a PHP expression, we can make the cached content to be variated according to the result of this PHP expression. This option has been available since version 1.0.4.
Request Types

有时候,我们希望片段缓存只对某些类型的请求启用。例如,对于某张网页上显示表单,我们只想要缓存initially requested表单(通过GET请求)。任何随后显示(通过POST请求)的表单将不被缓存,因为表单可能包含用户输入。要做到这一点,我们可以指定requestTypes 选项:

...其他HTML内容...
<?php if($this->beginCache($id, array(&#39;requestTypes&#39;=>array(&#39;GET&#39;)))) { ?>
...被缓存的内容...
<?php $this->endCache(); } ?>
...其他HTML内容...

2. 嵌套缓存(Nested Caching)

片段缓存可以嵌套。就是说一个缓存片段附在一个更大的片段缓存里。例如,意见缓存在内部片段缓存,而且它们一起在外部缓存中在文章内容里缓存。

...其他HTML内容...
<?php if($this->beginCache($id1)) { ?>
...外部被缓存内容...
  <?php if($this->beginCache($id2)) { ?>
  ...内部被缓存内容...
  <?php $this->endCache(); } ?>
...外部被缓存内容...
<?php $this->endCache(); } ?>
...其他HTML内容...

嵌套缓存可以设定不同的缓存选项。例如, 在上面的例子中内部缓存和外部缓存可以设置时间长短不同的持续值。当数据存储在外部缓存无效,内部缓存仍然可以提供有效的内部片段。 然而,反之就不行了。如果外部缓存包含有效的数据, 它会永远保持缓存副本,即使内容中的内部缓存已经过期。

5.缓存的使用:页面缓存

页面缓存

页面缓存指的是缓存整个页面的内容。页面缓存可以发生在不同的地方。 例如,通过选择适当的页面头,客户端的浏览器可能会缓存网页浏览有限时间。 Web应用程序本身也可以在缓存中存储网页内容。 在本节中,我们侧重于后一种办法。

页面缓存可以被看作是 片段缓存一个特殊情况 。 由于网页内容是往往通过应用布局来生成,如果我们只是简单的在布局中调用beginCache() 和endCache(),将无法正常工作。 这是因为布局在CController::render()方法里的加载是在页面内容产生之后。

如果想要缓存整个页面,我们应该跳过产生网页内容的动作执行。我们可以使用COutputCache作为动作 过滤器来完成这一任务。下面的代码演示如何配置缓存过滤器:

public function filters()
{
  return array(
    array(
      &#39;COutputCache&#39;,
      &#39;duration&#39;=>100,
      &#39;varyByParam&#39;=>array(&#39;id&#39;),
    ),
  );
}

上述过滤器配置会使过滤器适用于控制器中的所有行动。 我们可能会限制它在一个或几个行动通过使用插件操作器。 更多的细节中可以看过滤器。

Tip: 我们可以使用COutputCache作为一个过滤器,因为它从CFilterWidget继承过来, 这意味着它是一个工具(widget)和一个过滤器。事实上,widget的工作方式和过滤器非常相似: 工具widget (过滤器filter)是在action动作里的内容执行前执行,在执行后结束。

6.缓存的使用:动态内容

动态内容(Dynamic Content)

当使用fragment caching或page caching,我们常常遇到的这样的情况 整个部分的输出除了个别地方都是静态的。例如,帮助页可能会显示静态的帮助 信息,而用户名称显示的是当前用户的。

解决这个问题,我们可以根据用户名匹配缓存内容,但是这将是我们宝贵空间一个巨大的浪费,因为缓存除了用户名其他大部分内容是相同的。我们还可以把网页切成几个片段并分别缓存,但这种情况会使页面和代码变得非常复杂。更好的方法是使用由[ CController ]提供的动态内容dynamic content功能 。

动态内容是指片段输出即使是在片段缓存包括的内容中也不会被缓存。即使是包括的内容是从缓存中取出,为了使动态内容在所有时间是动态的,每次都得重新生成。出于这个原因,我们要求 动态内容通过一些方法或函数生成。

调用CController::renderDynamic()在你想的地方插入动态内容。

...别的HTML内容...
<?php if($this->beginCache($id)) { ?>
...被缓存的片段内容...
  <?php $this->renderDynamic($callback); ?>
...被缓存的片段内容...
<?php $this->endCache(); } ?>
...别的HTML内容...

在上面的, $callback指的是有效的PHP回调。它可以是指向当前控制器类的方法或者全局函数的字符串名。它也可以是一个数组名指向一个类的方法。其他任何的参数,将传递到renderDynamic()方法中。回调将返回动态内容而不是仅仅显示它。

希望本文所述对大家基于Yii框架的PHP程序设计有所帮助。

更多YII Framework框架教程之缓存用法详解相关文章请关注PHP中文网!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.