ThinkPHP 一键清空缓存需扩展 clear:all 命令:默认 php think clear 仅删 runtime 下目录,不处理 Redis、自定义路径、多应用及 Swoole 缓存;扩展命令需补全 Redis flush、自定义路径清理,并加环境校验、--force 强制确认、用户权限限制三重防护。

ThinkPHP 一键清空缓存,本质就是执行 php think clear 命令,但直接调用它常踩坑——比如清不干净、权限报错、线上误操作、或自定义缓存驱动(如 Redis)未被覆盖。
为什么 php think clear 有时清不干净?
默认命令只清 runtime/cache/ 和 runtime/data/ 目录,但以下情况会被跳过:
-
cache配置为redis或memcached时,think clear不连 Redis 执行FLUSHDB,只删本地文件 - 自定义缓存路径(如
'path' => '/tmp/tp_cache')不在runtime/下,命令不识别 - 多应用模式下,
app/multi_app_name/runtime/的缓存目录未被遍历 - 某些扩展(如
topthink/think-swoole)会把缓存存在runtime/swoole/,也不在清理范围内
如何安全扩展 clear 命令?
推荐在 app/command/ 下新建 ClearAll.php,继承原命令并补全逻辑:
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\Cache;
class ClearAll extends Command
{
protected function configure()
{
$this->setName('clear:all')->setDescription('Clear all cache including redis');
}
protected function execute(Input $input, Output $output)
{
// 1. 先跑原生 clear
$this->call('clear');
// 2. 清 Redis(仅当配置为 redis 且扩展可用)
if (Cache::getDriver() === 'redis') {
try {
Cache::handler()->flush();
$output->writeln('<info>Redis cache flushed.</info>');
} catch (\Throwable $e) {
$output->writeln('<error>Failed to flush Redis: ' . $e->getMessage() . '</error>');
}
}
// 3. 清自定义路径(示例:/tmp/tp_cache)
$customPath = '/tmp/tp_cache';
if (is_dir($customPath)) {
array_map('unlink', glob($customPath . '/*'));
rmdir($customPath);
$output->writeln('<info>Custom cache path cleared: ' . $customPath . '</info>');
}
}
}
注册后运行 php think clear:all 即可覆盖更多场景。
立即学习“PHP免费学习笔记(深入)”;
线上环境必须加的防护措施
运维脚本一旦放线上,没限制=高危。务必加三道锁:
- 检查当前环境:
if (app()->isProduction()) { throw new \RuntimeException('Not allowed in production'); } - 要求传参确认:
$input->getOption('force'),运行时必须加--force - 限制可执行用户:在 Shell 脚本中加
[[ "$(whoami)" == "www" ]] || { echo "Only www user allowed"; exit 1; }
Redis 缓存键名带前缀(如 think:)时,flush() 会清整个 DB,不是按前缀删——如果共用 DB,得改用 scan + del,这点容易被忽略。



















