かつて、Habrを読んで、キャッシュとタグについて尊敬されている
dmitrykoterovの 投稿に出会いました。 ちょうどそのとき、私はキャッシュで忙しかったので、多くの人と同じように、彼(キャッシュ)にはネイティブタグが実際にはないという結論に達しました。 これらのタグの下にリストされている変数の命名に入らずにハックします。 国内で最も人気のあるmemcacheについて話すと、サードパーティの開発者がこの機能の実装に携わっているのは奇妙です。
その結果、次の土曜日から日曜日のコードマラソンで、私はこの問題に厳密に対処し、memcacheであろうと純粋なphpのファイルキャッシュであろうと、キャッシュバックエンド用のユニバーサルライブラリを作成することにしました。 ライブラリは
googlecodeで記述され、解決され
ました 。 英語でごめんなさい、少し下に修正しようとします。
目標は、エレガントに書くことであり、どんなにひどく書かれていても、どのサイトにも簡単に実装できるようにすることでした。 シングルトンパターンは、移植のためだけでなく、パブリックメソッドへの静的な呼び出しだけのために選択されました。 現在サポートされているのはmemcacheのみですが、他のキャッシュシステム用のアダプターを作成するのは簡単です。
関数呼び出しがあるとします
$ res = GetMeaningOfLife(true、false、42);
熱核反応が起こる腸では、非常に複雑な計算が行われます。 したがって、キャッシュを
カットする必要があります。
すべては、キャッシングシステムのインストールから始まります
CacheTag :: SetBackend(CacheTag :: BACKEND_MEMCACHE);
次に、ライブラリにデータを取得するように教えます
CacheTag :: SetFunction( 'GetMeaningOfLife'、true、false、42);
ちなみに、「GetMeaningOfLife」の代わりに配列($ UniverseObject、「GetMeaningOfLife」)を書き込むと、データはUniverseObjectオブジェクトのGetMeaningOfLifeメソッドから抽出されます。
現在のキャッシュユニットには名前が付けられます。 これは、呼び出された関数/メソッドの名前、関数パラメーター、および以下で説明する追加のキャッシュパラメーターから形成されます。
次に、現在のキャッシュ要素にタグを付けます
CacheTag :: SetTags(CacheTag :: TAG_PURPOSE、CacheTag :: TAG_LIFE);
タグはCacheTag :: TAG_YOURTAGNAMEのように見えます。明らかにこれらは単なる定数です。 設定クラスで自分で宣言する必要があります。 ここで、ところで、「クラスの設定はなぜですか? そして、一般的に、なぜ別に、ファイルを2回間違えて計算したのですか?」 クラスは簡単に継承できます。 タグは便利な自動補完のために定数メソッドを使用して実装され、配列要素は異なります。実際、このクラスでは、主な機能に特に依存しない個人設定はすべて簡単で安全な更新用です。
実際、キャッシュに名前の目的を持つ変数があるか、TAG_PURPOSEに設定されていることに注意することは非常に重要です。 システムを最大限に活用するために、実際にはキャッシュ内の変数の値を既に識別する追加のパラメーターが必要です。 タグは、単純に論理的に残りを囲み、小さな値をグループで囲み、削除に便利です。
タグと同様に、パラメーターも定数です。 そして、それらはCacheTag :: PAR_YOURPARNAMEのように見えます。 これらは、1つのキャッシュユニットを別のキャッシュユニットと区別するために使用されます(eurykika!)。 パラメータを設定するには、メソッドを使用します
acheTag:: SetParam(CacheTag :: PARAM_PAGE、$ currentPageNum);
繰り返しますが、パラメータはオプション機能ではありません。 それらがなければ休日はありません。 また、変数名は明示的に設定されておらず、指定されたタグとパラメーターから組み立てられているため、タグの意味はなくなります。
かさばる関数が現在のユーザーに応じて結果を返す場合、または、たとえば、長いコンテンツでページが分割されている場合(ページネーションの読み取り)、モーメントは珍しくありません。 これらの変数は、グローバルおよびその他のトリックを使用して、関数によって暗黙的かつ魔法のように「キャスト」されます。 また、キャッシュ生成を開始する前に、便利かつ正確にパラメーターを指定すると非常に便利です。
これでデータを収集できます
$ res = CacheTag :: Fetch();
それだけです 最後に何がありますか:
だった
$ res = GetMeaningOfLife(true、false、42);
になっています
// $ res = GetMeaningOfLife(true、false、42);
CacheTag :: SetFunction( 'GetMeaningOfLife'、true、false、42);
CacheTag :: SetTags(CacheTag :: TAG_PURPOSE、CacheTag :: TAG_LIFE);
CacheTag :: SetParam(CacheTag :: PARAM_PAGE、$ currentPageNum);
$ res = CacheTag :: Fetch();
必要なのは、元の関数の呼び出しをコメントアウトして、数行追加することだけです。 追加のロジックやその他のif / elseはありません。
これ以降、データがキャッシュにない場合、データは自動的に取得され、構成に一定期間保存されます。 それ以外の場合、結果はキャッシュから返されます。
突然キャッシュをすぐに破棄する必要がある場合は、設定でキャッシュをオフにします。 すべての呼び出しは、指定された関数を強制的に通過します。 プロジェクト全体でのFidgetyの検索/置換はオプションです。
遅かれ早かれ、キャッシュを更新する必要が生じるときが来ます。 さて、たとえば、突然、あなたが持っている場合
新しいBabyBorn(「少年」); *
人生の意味が急変したので、方法が必要になります
CacheTag :: Flush();
CacheTag :: Fetch();の代わりに使用されます。 つまり このセットに対応する必要なタグ、パラメータ、変数を設定すると、削除のマークが付けられます。
すべて、過去の人生の意味はもはや関係ありません。 次の控訴で、それは再び取られるでしょう。
ちなみに、プログラマーにとっては、生成されたhtmlコンテンツ(print / echo / ...)を必要に応じて出力して中央に表示するのではなく、出力することは初心者にとっても珍しくありません(個人的にはob_ *でもこれを正当化しないと思います) ) コンテンツは、キャッシュから呼び出される関数など、いくつかの場所に表示できます。 そのようなプロジェクトは、コードを変更せずに標準的な方法でキャッシュするのは簡単ではない場合があります。怖くない場合はどうすればよいのでしょうか。 しかし、phpCacheTagへの賞賛、この問題はこれから私たちを悩ませません。 同じ名前のキャッシュには、戻り値と、関数/メソッドの実行中に標準ストリームにリリースされたコンテンツの両方が格納されます。 このコンテンツは、関数の実際の操作中のように、この変数への要求に応じて表示(印刷)されます。
上記のすべてをまとめると、すべてを最も簡単な例にまとめます。
error_reporting(E_ALL);
require_once( "CacheTag.class.php");
関数f()
{
睡眠(1);
return 2;
}
CacheTag :: SetBackend(CacheTag :: BACKEND_MEMCACHE);
CacheTag :: SetFunction( 'f');
CacheTag :: SetTags(CacheTag :: TAG_PRODUCT);
CacheTag :: SetParam(CacheTag :: PARAM_ID、2);
CacheTag :: SetTimeout(0.1);
CacheTag :: Fetch();
構成クラスで定数タグ、パラメーター、およびバックエンドを作成します。 ところで、それらの値は重要ではありません。主なことは、それらが重ならないことです。
概して、これですべてです。 私は自分が優秀なプログラマーになるように強制し、このすべてについて完全なドキュメントを書きます。
それまでの間、
試して 、建設的に批判し、バグ報告してください。
ハッピーコーディング。
更新(2010年8月24日):
バージョン:0.1.5
- バグ:Flush()を呼び出した後に設定がリセットされない
- バグ:Replace()のデバッグメッセージがありません
- 変更:example.phpの変更
- 変更:不要な場合にキャッシュにアクセスしないように、Fetch()を変更しました
- 変更:ゼロの時間制限値を使用することが可能です
- 変更:Memcacheはlocalhostの代わりに127.0.0.1を使用します
* BabyBornクラスはライブラリの一部ではありません。 必要に応じて、自分で作成できます。