CakePHP2.4.0からデバッグモードならファイルキャッシュ用フォルダを作る様になった

そのうち書こうと思ってたら、すっかり遅れた話になってしまいました。

$ tree
.
├── cache
│   ├── models
│   ├── persistent
│   └── views
├── logs
├── sessions
└── tests

APP/tmpの中は大抵こんなフォルダ構成になっていると思います。cacheフォルダとか、使う時に自動生成してくれるんだろうなと思って、あえて作らずに動かすと、少し前までは、エラーになっていました。
それがCakePHP 2.4.0から、デバッグモードなら自動生成する様になっていたという話です。
まぁそれだけなんですけど。

ついでに、logsフォルダも、デバッグモードなら自動生成する様になっている様です。

コードで見る

allow creating of missing tmp directories in debug (development) mode fo… · f5859ca · cakephp/cakephp

実際に動きが変わったのは、このコミットからです。コミットコメントや、diffを見ての通りだけど、ファイルキャッシュのFileEngineとログのFileLogでmkdir()をするコードが追加されています。

パーミッションについて

追加されたコードではmkdir($path, 0775, true)という風にパーミッションも指定してあります。でもmkdir()は引数よりumask()での設定を優先すると思うので、あまり意味は無い様な気がします。

testmkdirは引数よりumaskを優先する · d21593f · kanonji/phptesting

Cache::config('_cake_core_', array(
        'engine' => 'File',
[snip]
        'mask' => 0666,
));

こんな感じでCacheの設定にmaskというのを追加する事で、パーミッションを指定出来るので、結局これが必要だと思います。

if (!$exists && !chmod($this->_File->getPathname(), (int)$this->settings['mask'])) {

https://github.com/cakephp/cakephp/blob/f5859ca7193dcd82433fb0f617d64b1fbd380801/lib/Cake/Cache/Engine/FileEngine.php#L319

ちなみに、このmaskはこの様にchmod()への引数にそのまま使われててmaskでは無い様な気がするけどどうなんだろう。

SplFileInfo::openFileという警告について

Warning: SplFileInfo::openFile([snip]

このcacheフォルダのパーミッションが原因で、CakePHPではこのWarningを出しちゃう事が多いです。
基本的にパーミッションが原因なので、上記のmaskを適切に設定すれば解決するはずです。

よくハマるのがCakeShellで何かを作ってる場合、Apache実行ユーザーと、sshでログインしてcake some_shellの様なコマンドを実行するユーザーが違う為に、パーミッションが無いというケースです。
両方同じグループに入れて775にするとかの対応が必要です。

このSplFileInfo::openFileに関しては、もうちょっと書ける事があったような気がするけど、時間が経ちすぎて忘れちゃいました。

余談

ファイルキャッシュを使わずにキャッシュエンジンをMemcacheとかにしているなら、そもそもファイルは生成されないしパーミッションは関係ないぜと思っているとハマる事があります。

protected function _saveState(Controller $controller, $vars) {
[snip]
        Cache::write($this->cacheKey, $history, 'debug_kit');
}

https://github.com/cakephp/debug_kit/blob/2.2.2/Controller/Component/ToolbarComponent.php#L501

CakePHP2ではほぼデフォルト扱いっぽいDebugKitを使っていると、DebugKitが内部でキャッシュをファイルに書き出しています。
DebugKitはデバッグモードでしか使わないはずだし、CakePHP 2.4.0からキャッシュに使うフォルダの自動生成もデバッグモードでならする様になったから、基本的には問題にはならないと思うけど、使ってないはずのファイルキャッシュでパーミッションのエラーが出た場合は、DebugKitや他のプラグインが怪しいかも。

protected function _createCacheConfig() {
        if (Configure::read('Cache.disable') === true || Cache::config('debug_kit')) {
                return;
        }
        $cache = array(
            'duration' => $this->cacheDuration,
            'engine' => 'File',
            'path' => CACHE
        );
        if (isset($this->settings['cache'])) {
                $cache = array_merge($cache, $this->settings['cache']);
        }
        Cache::config('debug_kit', $cache);
}

https://github.com/cakephp/debug_kit/blob/2.2.2/Controller/Component/ToolbarComponent.php#L390

一応、コントローラーに書くToolbarComponentの設定で、キャッシュエンジンの指定は出来そうですが。

環境

環境 バージョン
CakePHP 2.4.0

書いた日

2014年1月18日

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>