Yii 2缓存文件权限异常引发filemtime报错,如何规避首次加载警告?
解决Yii2 FileCache首次加载filemtime错误的几种方法
这问题我碰到过好几次,Yii2的FileCache在缓存文件首次创建前确实会抛出这个小错误——本质是缓存还没生成时框架就去调用filemtime()检查文件状态,属于良性报错,但被Slack机器人反复推送确实闹心。下面给你几个实用的解决思路:
方法一:自定义缓存类,从根源避免报错
直接修改vendor里的FileCache.php肯定不行(更新依赖会覆盖),我们可以继承原类并重写相关方法,提前检查文件是否存在:
- 在你的项目里创建一个自定义缓存类,比如
app/components/CustomFileCache.php:
namespace app\components; use yii\caching\FileCache; class CustomFileCache extends FileCache { /** * 重写getValue方法,先检查缓存文件是否存在 */ protected function getValue($key) { $cacheFile = $this->getCacheFile($key); // 文件不存在直接返回false,避免触发filemtime错误 if (!file_exists($cacheFile)) { return false; } // 调用父类原逻辑 return parent::getValue($key); } }
- 修改应用配置文件(
config/web.php或config/main.php),把默认的cache组件替换成这个自定义类:
'components' => [ 'cache' => [ 'class' => 'app\components\CustomFileCache', // 保留你原来的FileCache配置,比如cachePath等 'cachePath' => '@runtime/cache', ], ],
这个方法最彻底,从代码层面杜绝了错误的产生,适合长期解决。
方法二:调整日志配置,过滤掉这个无用警告
如果不想改代码,最快的方式是在日志配置里把这个错误过滤掉,或者降低它的级别,让Slack机器人抓不到:
方案A:在Slack日志Target里排除FileCache的日志
找到你配置Slack监控的地方(一般在log targets里),添加categories排除规则:
'log' => [ 'targets' => [ // 其他日志Target... [ 'class' => 'yii\log\SlackTarget', 'categories' => ['!yii\caching\FileCache'], // 排除FileCache类的所有日志 'webHook' => '你的Slack WebHook地址', // 其他Slack配置... ], ], ],
方案B:把FileCache的错误降级为调试级别
如果还想保留这个日志但不触发告警,可以把它的级别调低:
'log' => [ 'targets' => [ [ 'class' => 'yii\log\FileTarget', 'categories' => ['yii\caching\FileCache'], 'levels' => 'info, debug', // 只记录info和debug级,不记录error ], // Slack Target配置... ], ],
这个方法最快,不用改动业务逻辑,适合临时快速解决。
方法三:提前预生成缓存文件
如果你的缓存内容是固定或可提前生成的,可以在应用启动时预先生成缓存,这样用户首次访问时缓存已经存在,就不会触发错误了:
比如在web/index.php(Web应用)或console/bootstrap.php(控制台应用)里添加预缓存逻辑:
// 初始化应用后 $application = new yii\web\Application($config); // 预生成需要的缓存 $cache = $application->cache; // 用getOrSet确保缓存不存在时自动生成 $cache->getOrSet('myapp03eab921185f7b68bbca50d8debc0dda', function() { // 这里写你的缓存生成逻辑,比如查询数据库、读取配置等 return '你的缓存内容'; }); $application->run();
这个方法适合缓存内容固定的场景,能彻底避免首次加载的报错,但需要你明确知道哪些缓存会被触发。
内容的提问来源于stack exchange,提问作者Bobs
相关产品推荐
相关产品推荐

