数组文件 + t() 这套是最省心的起点,中小站(词条 < 1000、语言 ≤ 3 种)我建议直接用到底,别一上来就上 gettext。

往下说几个你帖子还没展开的方案,顺带把数组方案的坑先讲了。

方案二 gettext(.po/.mo):工具链最成熟,Poedit 能让翻译人员完全不碰代码,性能也好。但坑在 PHP-FPM:setlocale() 是进程级的,多个用户不同语言会互相污染,必须用 putenv + 每请求重设,或者干脆用 bindtextdomain 指定目录后只切 domain 不切 locale。另外 .mo 要先编译,部署流程多一步。

方案三 数据库 + 缓存:适合要在后台给运营在线改文案的场景,配合 Cache::remember 缓存整份词典,请求级读一次即可,代价是多一张表和一层缓存失效逻辑。

方案四 JSON 文件:前后端都能读,适合 PHP 模板和 JS 要共用词条的站。

数组方案自己的坑:strtr 是按 key 最长优先匹配的,所以 :name 和 :name_full 一起用不会误伤,可以放心;但复数它处理不了(英文 1 item / 2 items),中文无所谓,做多语言就得自己写 t() 的复数分支或用 ICU 格式。日期和数字也别硬编码 date('Y-m-d'),单独抽 formatDate() 按语言出格式。最后,OPcache 生产开、开发环境记得 revalidate_freq=0,不然改了语言文件看不到效果会怀疑人生。