thinkphp 8.0 关闭字段缓存需手动清除 runtime/schema/ 目录或调用 db::clearcache(),仅配置 'fields_cache' => false 无效;必须验证 is_file(runtime_path() . 'schema/mysql_user.php') 返回 false,且用 db::name('user')->getfields(true) 强制查库确认新字段生效。

ThinkPHP 8.0 关闭缓存不是“一键关掉”就能完事的——字段缓存(schema cache)不更新,Unknown column 错误会直接报在 SQL 层,模型查不到新字段、where() 条件静默失效、甚至 save() 写入空值。关键不是关不关,而是关哪一层、怎么验证真关了。
关字段缓存:别只改配置,先清 runtime/schema/
字段缓存默认开启,且不随 php think clear --all 清除。它独立存在,路径是 runtime/schema/,文件名如 mysql_user.php。哪怕你在 config/database.php 里把 'fields_cache' => false 写对了,旧缓存文件还在,TP 就仍会优先读它。
- 开发阶段最稳妥做法:删掉整个
runtime/schema/目录(或至少删对应表的 PHP 文件),再跑一次查询触发重新生成 - 命令行快捷清理:
php think clear:cache不管用;必须手动rm -rf runtime/schema/或调用\think\facade\Db::clearCache() - 确认是否真清了:执行
var_dump(is_file(runtime_path() . 'schema/mysql_user.php')),返回false才算成功 - 如果用了 Redis 做 schema 缓存,
Db::clearCache()会清 Redis 中以think_schema_开头的 key,但得确保schema_cache_type配置在数据库连接内(不是全局 config)
关模板/路由/配置缓存:APP_DEBUG=false 是前提
模板编译缓存(runtime/view/)、路由缓存(runtime/route.php)、配置缓存(runtime/config.php)都只在 APP_DEBUG = false 时生效。很多人改了模板或路由却没效果,其实是 .env 里还留着 APP_DEBUG=true,或者 config/app.php 里硬编码了 'app_debug' => true。
- 验证当前状态:
dump(\think\App::debug())输出false才表示缓存真正启用 - 清模板缓存必须加
-t参数:php think clear -t,否则runtime/view/下的文件不会动 - 清路由缓存不能只删
runtime/route.php:要用php think clear:route,它还会清理关联的临时索引文件 - 配置缓存更新后,若
config('app.app_name')还是旧值,可能是 PHP OpCache 没刷新,需重启 PHP-FPM 或调用opcache_reset()
字段缓存导致 SQL 报错的典型表现与修复路径
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'new_field' in 'field list' 这类错误,90% 是字段缓存没同步,而不是 SQL 写错了。它发生在模型写入或自动构造 SELECT 字段时,框架拿着过期的字段列表去拼 SQL。
- 先绕过缓存验证:临时把
config/database.php里对应连接的'fields_cache' => false,然后重启请求——如果错误消失,就坐实是字段缓存问题 - 不要依赖
Db::name('user')->getFields()返回结果来判断:这个方法会走缓存,得加force参数强制查库:Db::name('user')->getFields(true) - 上线后加字段,必须走两步:① 执行 DDL(如
ALTER TABLE user ADD COLUMN new_field VARCHAR(255));② 立即运行\think\facade\Db::clearCache()或删runtime/schema/ - 如果用多数据库连接,每个连接的字段缓存是隔离的,
Db::clearCache()默认只清当前连接,要清全部得循环调用或手动删文件
为什么 Cache::clear() 在控制器里没反应?
不是代码写错了,而是缓存驱动根本没初始化或被 fallback 到了 null 驱动。尤其在中间件、命令行或异步任务中,容器可能没完整加载。
- 别依赖默认 store:
Cache::store('file')->clear()比Cache::clear()可靠得多 - 检查
config/cache.php中'default'值是否被.env覆盖,比如CACHE_STORE=redis但 Redis 服务不可达,就会静默降级到null - 验证是否真删了:
var_dump(Cache::store('file')->get('test_key')),别只信clear()返回true - 标签缓存(
Cache::tag('user')->clear())在 APC、WinCache 驱动下完全无效,只有file、redis、memcached支持真正穿透
字段缓存的问题不在“关不关”,而在“何时清、清哪里、怎么验”。runtime/schema/ 下的文件不手动删或不调 Db::clearCache(),光改配置等于没改;而清了之后不验证 getFields(true) 是否返回新字段,就永远不知道有没有真正生效。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











