キャッシュ動作が有効の際に、閲覧する固定ページの内容に、他のページ内容が表示されてしまう場合が稀にあります。
- キャッシュが有効なのは通常動作
- 管理側にログイン中は再現されない(閲覧時にキャッシュが利用されないため)
- debugモードが 1 の場合は再現されない(閲覧時にキャッシュが利用されないため)
キャッシュの利用を抑制することでお手軽に解決できますが、表示パフォーマンスが落ちるため原因を調べてみました。
install.php
Configure::write('Cache.disable', true);
発生したタイミングと環境
固定ページのキャッシュが生成されたあと、そのキャッシュファイルが、他の固定ページ表示(URLの表示)のタイミングで利用されてしまうとき。
環境
- 大塚商会: アルファメールプレミア: http://www.alpha-prm.jp/
- PHP 5.3.3
- baserCMS 3.0.5
原因
Inflector::slug() での文字列生成に失敗している。
/lib/Baser/Routing/Filter/BcCacheDispatcher.php
$path = strtolower(Inflector::slug($path));
ここで生成される文字列は、固定ページ用のキャッシュファイル名となっている。
例:/app/tmp/cache/views/hoge_fuga.php
※「/」はアンダースコアに変換される
対策
/lib/Cake/Utility/Inflector.php の slug() をcake 1.2.12(/cake/libs/inflector.php)の内容にする。
- /lib/Cake/Utility/Inflector.php を /app/Utility/Inflector.php にコピーする
- slug() の内容を以下に書換える
/app/Utility/Inflector.php
public static function slug($string, $replacement = '_') {
if ($_SERVER["SERVER_NAME"] == 'example.com') {
// 本番環境で cacheファイルが正しく生成されないため、
// cake 1.2.12(/cake/libs/inflector.php)のコードを適用
App::uses('String', 'Utility');
$map = array(
'/à|á|å|â/' => 'a',
'/è|é|ê|ẽ|ë/' => 'e',
'/ì|í|î/' => 'i',
'/ò|ó|ô|ø/' => 'o',
'/ù|ú|ů|û/' => 'u',
'/ç/' => 'c',
'/ñ/' => 'n',
'/ä|æ/' => 'ae',
'/ö/' => 'oe',
'/ü/' => 'ue',
'/Ä/' => 'Ae',
'/Ü/' => 'Ue',
'/Ö/' => 'Oe',
'/ß/' => 'ss',
'/[^\w\s]/' => ' ',
'/\\s+/' => $replacement,
String::insert('/^[:replacement]+|[:replacement]+$/', array('replacement' => preg_quote($replacement, '/'))) => '',
);
return preg_replace(array_keys($map), array_values($map), $string);
} else {
$quotedReplacement = preg_quote($replacement, '/');
$merge = array(
'/[^\s\p{Zs}\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]/mu' => ' ',
'/[\s\p{Zs}]+/mu' => $replacement,
sprintf('/^[%s]+|[%s]+$/', $quotedReplacement, $quotedReplacement) => '',
);
$map = self::$_transliteration + $merge;
return preg_replace(array_keys($map), array_values($map), $string);
}
}
確認
- /app/tmp/cache/views 内に生成されるキャッシュファイルが、URLをベースにしたファイル名で生成されていればOK
- 固定ページのキャッシュ生成後、閲覧する固定ページの内容に、他のページ内容が表示されなければOK