CS-Cartでアドオンを開発しているとキャッシュをクリアすることがありますが、なぜかキャッシュがクリアできない問題に遭遇しました。
CS-Cartのキャッシュクリア機能は最終的にfn.fs.phpのfn_rm
関数を呼んでいるのですが、実装が「ひとつでもファイル削除失敗したら中断する」ようになっています。中断されても、画面には「お知らせ キャッシュがクリアされました」とあたかもうまくいっているようなフィードバックがありますが、嘘っぱちです(苦笑)。
fn_rm
関数を見てみましょう。ファイルでだったらunlink
、ディレクトリだったら子ファイルを再帰呼び出しでunlink
してからディレクトリをrmdir
するといった、PHPあるあるなコードになっています。しかし、よく見てみると、ディレクトリ内のファイル削除がひとつでも失敗したらreturn false
して処理を中断するようになっています。
/**
* Recursively remove directory (or just a file)
*
* @param string $source
* @param bool $delete_root
* @param string $pattern
* @return bool
*/
function fn_rm($source, $delete_root = true, $pattern = '')
{
// Simple copy for a file
if (is_file($source)) {
$res = true;
if (empty($pattern) || (!empty($pattern) && preg_match('/' . $pattern . '/', fn_basename($source)))) {
$res = @unlink($source);
}
return $res;
}
// Loop through the folder
if (is_dir($source) && $dir = dir($source)) {
while (false !== $entry = $dir->read()) {
// Skip pointers
if ($entry == '.' || $entry == '..') {
continue;
}
if (fn_rm($source . '/' . $entry, true, $pattern) == false) {
return false; /* ここで諦めちゃう… */
}
}
// Clean up
$dir->close();
return ($delete_root == true && empty($pattern)) ? @rmdir($source) : true;
} else {
return false;
}
}
こうなってしまっては画面からのキャッシュクリアはできませんので、コマンドでさくっと削除してしまいましょう。
rm -rf var/cache/registry/*