Yii は、高性能 PHP5 Web アプリケーション開発フレームワークです。シンプルなコマンド ライン ツール yiic を使用すると、Web アプリケーション コード フレームワークを迅速に作成でき、開発者は生成されたコード フレームワークに基づいてビジネス ロジックを追加して、アプリケーション開発を迅速に完了できます。キャッシュは、Web サイトのパフォーマンスを向上させるためのシンプルかつ効果的な方法です。わずかに大きなサイズの Web サイトでは、必要なときに備えて比較的静的なデータがキャッシュに保存されるため、クエリを実行してデータベースからデータを生成する時間を節約し、データベースへの負荷を軽減して Web サイトのパフォーマンスを向上させることができます。強力な PHP オープンソース フレームワークとして、Yii はさまざまな一般的なキャッシュのインターフェイスを提供し、実際のニーズに応じてさまざまなキャッシュを使用できます。
yii のキャッシュ関連コンポーネントは yii/framework/caching ディレクトリに保存されています。このディレクトリを参照すると、yii がどのキャッシュをサポートしているかを知ることができます。以下に関連ファイルを簡単に紹介します。
CMemCache: PHP memcache 拡張機能を使用します。
CApcCache: PHP APC 拡張機能を使用します。
CXCache: PHP XCache 拡張機能を使用します。これはバージョン 1.0.1 からサポートされることに注意してください。
CEAcceleratorCache: PHP EAccelerator 拡張機能を使用します。
CDbCache: データ テーブルを使用してキャッシュ データを保存します。デフォルトでは、ランタイム ディレクトリに SQLite3 データベースが作成され、使用されます。 connectionID プロパティを設定することで、使用するデータベースを指定することもできます。
CZendDataCache: Zend Data Cache をバックエンド キャッシュ メディアとして使用します。これはバージョン 1.0.4 以降でサポートされることに注意してください。
CFileCache: ファイルを使用してキャッシュ データを保存します。これは、大きなデータの塊 (ページなど) を保存する場合に特に便利です。これはバージョン 1.0.6 以降でサポートされることに注意してください。
CDummyCache: 現在、ダミーキャッシュはキャッシュ機能を実装していません。このコンポーネントの目的は、キャッシュの可用性を確認する必要があるコードを簡素化することです。たとえば、このキャッシュ コンポーネントは、開発段階中、またはサーバーが実際のキャッシュ機能をまだサポートしていないときに使用できます。実際のキャッシュ サポートが有効になっている場合は、対応するキャッシュ コンポーネントの使用に切り替えることができます。どちらの場合も、同じコード Yii::app()->cache->get($key) を使用して、Yii::app()->cache が null である可能性を気にせずにデータ フラグメントを取得できます。このコンポーネントはバージョン 1.0.5 以降でサポートされています。
ヒント: これらすべてのキャッシュ コンポーネントは同じ基本クラス CCache から継承しているため、キャッシュを使用するコードを変更せずに別のキャッシュ メソッドに切り替えることができます。
Yii でのキャッシュの使用には、主にキャッシュコンポーネントの設定とアクセスが含まれます。 次の 2 つの説明は、それぞれ memcache キャッシュ コンポーネントとファイル キャッシュ コンポーネントの使用に基づいています:
(1) memcache キャッシュの例:
次のアプリケーション構成は、2 つのキャッシュ サーバーを使用して memcache キャッシュ コンポーネントを指定します:
array( ...... 'components'=>array( ...... 'phpernote_cache'=>array( 'class'=>'system.caching.CMemCache', 'servers'=>array( array('host'=>'10.201.1.101', 'port'=>11211, 'weight'=>60), array('host'=>'10.201.1.102', 'port'=>11211, 'weight'=>40), ), ), ), );
が実行されている場合、コントローラー メソッドの Yii::app()->phpernote_cache を通じてキャッシュ コンポーネントにアクセスできます。例:
Yii::app ()->phpernote_cache->set($key,$value) ,$expire);
Yii::app()->phpernote_cache->add($id,$value);
Yii::app()->phpernote_cache->get($key);
(2) ファイルキャッシュの例:
1. キャッシュ設定情報を設定ファイルに追加します
array( ...... 'components'=>array( ...... 'cache'=>array( 'class'=>'system.caching.CFileCache', 'directoryLevel'=>2 ), ), ), );
上記の設定では、キャッシュされたページが多すぎる場合、この値はキャッシュされたファイルのディレクトリの深さを設定する必要があります。大きく設定しないと、各ディレクトリに多くのページが存在することになります。
2. キャッシュするコントローラーでフィルターを定義します。
public function filters(){ return array( array( 'COutputCache + post, list', 'duration'=>3600, 'varyByParam'=>array('id','page'), 'dependency'=>array( 'class'=>'CDbCacheDependency', 'sql'=>'SELECT MAX(id) FROM phpernote_article', ) ); }
COutputCache は、「COutputCache」のみを入力すると、「COutputCache + post, list」を定義すると、次のメソッドのみがフィルター処理されます。キャッシュされる: actionPost、actionList 。
duration は秒単位のキャッシュ時間です。
varyByParam は GET パラメータ名のリストを指定し、対応する値を使用してキャッシュされたコンテンツのバージョンを決定します。つまり、同じアクションが異なるページのパラメータを区別するために使用されます。これは、異なるページを区別するために ID とページを使用します。
varyByParam に加えて、他の条件もページを区別するために使用できます:
varyByExpression: カスタム PHP 式の結果に基づいて変更するキャッシュ コンテンツを指定します。
varyByRoute: のルートに基づいて変更するキャッシュ コンテンツを指定します。リクエスト (コントローラーとアクション)
varyBySession: コンテンツをキャッシュするかどうかを指定します。
dependency はキャッシュ無効化の依存関係を指定します。この例では、データベースの依存関係を指定します。データ テーブルの特定の値が変更されることで、キャッシュの有効期限が切れているかどうかが判断されます。たとえば、新しいレコードがテーブルに追加されると、キャッシュが 5 分間しかキャッシュされていない場合でも (
ヒント: Yii は Redis もサポートします。プラグインをインストールする必要があります: http://www.yiibase.com/download/view/32.html
缓存可以在不同的级别使用。在最低级别,可用来缓存单个数据(数据缓存)。往上一级,我们缓存一个由视图脚本生成的页面片断(片段缓存)。在最高级别,可存储整个页面以便需要的时候直接从缓存读取。本文说明页面缓存的配置及实现效果;
数据缓存
数据缓存即存储一些 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['username']=$value1; // 相当于: $cache->set('username',$value1); $value2=$cache['username']; // 相当于: $value2=$cache->get('username');
1. 缓存依赖
除了过期设置,缓存数据也可能会因为依赖条件发生变化而失效。例如,如果我们缓存了某些文件的内容,而这些文件发生了改变,我们就应该让缓存的数据失效,并从文件中读取最新内容而不是从缓存中读取。
我们将一个依赖关系表现为一个 CCacheDependency 或其子类的实例。 当调用 set() 时,我们连同要缓存的数据将其一同传入。如下面这段代码的意思就是此值将在30秒后失效,但如果依赖的文件发生了变化则立即失效:
Yii::app()->cache->set($id, $value, 30, new CFileCacheDependency('FileName'));
现在如果我们通过调用get() 从缓存中获取 $value ,依赖关系将被检查,如果发生改变,我们将会得到一个 false 值,表示数据需要被重新生成。
如下是可用的缓存依赖的简要说明:
CFileCacheDependency: 如果文件的最后修改时间发生改变,则依赖改变。
CDirectoryCacheDependency: 如果目录和其子目录中的文件发生改变,则依赖改变。
CDbCacheDependency: 如果指定 SQL 语句的查询结果发生改变,则依赖改变。
CGlobalStateCacheDependency: 如果指定的全局状态发生改变,则依赖改变。全局状态是应用中的一个跨请求,跨会话的变量。它是通过 CApplication::setGlobalState() 定义的。
CChainedCacheDependency: 如果链中的任何依赖发生改变,则此依赖改变。
CExpressionDependency: 如果指定的 PHP 表达式的结果发生改变,则依赖改变。此类从版本 1.0.4 起可用。
片段缓存(Fragment Caching)
片段缓存指缓存网页某片段。例如,如果一个页面在表中显示每年的销售摘要,我们可以存储此表在缓存中,减少每次请求需要重新产生的时间。
要使用片段缓存,在控制器视图脚本中调用 CController::beginCache() 和 CController::endCache() 。这两种方法开始和结束包括的页面内容将被缓存。类似data caching ,我们需要一个编号,识别被缓存的片段。例如下面这段代码如果beginCache() 返回false,缓存的内容将此地方自动插入; 否则,在if语句内的内容将被执行并在endCache()触发时缓存。
...... <?php if($this->beginCache($id)) { ?> ...被缓存的内容... <?php $this->endCache(); } ?> ......
1. 缓存选项(Caching Options)
当调用beginCache(),可以提供一个数组由缓存选项组成的作为第二个参数,以自定义片段缓存。事实上为了方便,beginCache() 和endCache()方法是[ COutputCache ]widget的包装。因此COutputCache的所有属性都可以在缓存选项中初始化。
有效期(Duration)
也许是最常见的选项是duration,指定了内容在缓存中多久有效。和CCache::set()过期参数有点类似。下面的代码缓存内容片段最多一小时:
...... <?php if($this->beginCache($id, array('duration'=>3600))) { ?> ...被缓存的内容... <?php $this->endCache(); } ?> ......
如果我们不设定期限,它将默认为60 ,这意味着60秒后缓存内容将无效。
依赖(Dependency)
像data caching ,内容片段被缓存也可以有依赖。例如,文章的内容被显示取决于文章是否被修改。
要指定一个依赖,我们建立了dependency选项,可以是一个实现[ICacheDependency]的对象或可用于生成依赖对象的配置数组。下面的代码指定片段内容取决于lastModified 列的值是否变化:
<?php if($this->beginCache($id, array('dependency'=>array( 'class'=>'system.caching.dependencies.CDbCacheDependency', 'sql'=>'SELECT MAX(lastModified) FROM Post')))) { ?> ...被缓存的内容... <?php $this->endCache(); } ?
变化(Variation)
缓存的内容可根据一些参数变化。例如,每个人的档案都不一样。缓存的档案内容将根据每个人ID变化。这意味着,当调用beginCache()时将用不同的ID。
COutputCache内置了这一特征,程序员不需要编写根据ID变动内容的模式。以下是摘要。
varyByRoute: 设置此选项为true ,缓存的内容将根据route变化。因此,每个控制器和行动的组合将有一个单独的缓存内容。
varyBySession: 设置此选项为true ,缓存的内容将根据session ID变化。因此,每个用户会话可能会看到由缓存提供的不同内容。
varyByParam: 设置此选项的数组里的名字,缓存的内容将根据GET参数的值变动。例如,如果一个页面显示文章的内容根据id的GET参数,我们可以指定varyByParam为array('id'),以使我们能够缓存每篇文章内容。如果没有这样的变化,我们只能能够缓存某一文章。
有时候,我们希望片段缓存只对某些类型的请求启用。例如,对于某张网页上显示表单,我们只想要缓存initially requested表单(通过GET请求)。任何随后显示(通过POST请求)的表单将不被缓存,因为表单可能包含用户输入。要做到这一点,我们可以指定 requestTypes 选项:
<?php if($this->beginCache($id, array('requestTypes'=>array('GET')))) { ?> ...被缓存的内容... <?php $this->endCache(); } ?>
2. 嵌套缓存(Nested Caching)
片段缓存可以嵌套。就是说一个缓存片段附在一个更大的片段缓存里。例如,意见缓存在内部片段缓存,而且它们一起在外部缓存中在文章内容里缓存。
<?php if($this->beginCache($id1)) { ?> ...外部被缓存内容... <?php if($this->beginCache($id2)) { ?> ...内部被缓存内容... <?php $this->endCache(); } ?> ...外部被缓存内容... <?php $this->endCache(); } ?>
嵌套缓存可以设定不同的缓存选项。例如,在上面的例子中内部缓存和外部缓存可以设置时间长短不同的持续值。当数据存储在外部缓存无效,内部缓存仍然可以提供有效的内部片段。然而,反之就不行了。如果外部缓存包含有效的数据, 它会永远保持缓存副本,即使内容中的内部缓存已经过期。
页面缓存
页面缓存指的是缓存整个页面的内容。页面缓存可以发生在不同的地方。例如,通过选择适当的页面头,客户端的浏览器可能会缓存网页浏览有限时间。Web应用程序本身也可以在缓存中存储网页内容。 在本节中,我们侧重于后一种办法。
页面缓存可以被看作是 片段缓存一个特殊情况 。 由于网页内容是往往通过应用布局来生成,如果我们只是简单的在布局中调用beginCache() 和endCache(),将无法正常工作。这是因为布局在CController::render()方法里的加载是在页面内容产生之后。
如果想要缓存整个页面,我们应该跳过产生网页内容的动作执行。我们可以使用COutputCache作为动作 过滤器来完成这一任务。下面的代码演示如何配置缓存过滤器:
public function filters(){ return array( array( 'COutputCache', 'duration'=>100, 'varyByParam'=>array('id'), ), ); }
上述过滤器配置会使过滤器适用于控制器中的所有行动。 我们可能会限制它在一个或几个行动通过使用插件操作器。 更多的细节中可以看过滤器。
提示: 我们可以使用COutputCache作为一个过滤器,因为它从CFilterWidget继承过来, 这意味着它是一个工具(widget)和一个过滤器。事实上,widget的工作方式和过滤器非常相似。工具widget (过滤器filter)是在action动作里的内容执行前执行,在执行后结束。
6.缓存的使用:动态内容(Dynamic Content)
当使用fragment caching或page caching,我们常常遇到的这样的情况 整个部分的输出除了个别地方都是静态的。例如,帮助页可能会显示静态的帮助 信息,而用户名称显示的是当前用户的。
解决这个问题,我们可以根据用户名匹配缓存内容,但是这将是我们宝贵空间一个巨大的浪费,因为缓存除了用户名其他大部分内容是相同的。我们还可以把网页切成几个片段并分别缓存,但这种情况会使页面和代码变得非常复杂。更好的方法是使用由[ CController ]提供的动态内容dynamic content功能 。
动态内容是指片段输出即使是在片段缓存包括的内容中也不会被缓存。即使是包括的内容是从缓存中取出,为了使动态内容在所有时间是动态的,每次都得重新生成。出于这个原因,我们要求 动态内容通过一些方法或函数生成。
调用CController::renderDynamic()在你想的地方插入动态内容。
<?php if($this->beginCache($id)) { ?> ...被缓存的片段内容... <?php $this->renderDynamic($callback); ?> ...被缓存的片段内容... <?php $this->endCache(); } ?>
在上面的,$callback指的是有效的PHP回调。它可以是指向当前控制器类的方法或者全局函数的字符串名。也可以是一个数组名指向一个类的方法。其他任何的参数,将传递到 renderDynamic()方法中。回调将返回动态内容而不是仅仅显示它。
关于Yii框架缓存的知识这篇文章基本做了一个总结,希望大家在工作当中能用的到。
相关推荐:
以上がPHP-yiiフレームワークキャッシュのナレッジコレクションの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。