feehicms是一款基于yii2框架、全面测试驱动的开源cms系统,提供rbac权限、restful api、多语言、docker一键部署及sqlite/mysql/postgresql支持,旨在让开发者专注业务开发而非重复造轮子。

Yii2 本身不是 CMS,它是一个框架——你没法“用 Yii2 开发 CMS”像搭积木一样点几下就出来。真正可行的路径是:**复用成熟 Yii2-CMS 项目,按需裁剪和扩展**。硬从零写一套通用 CMS,投入产出比极低,且大概率踩遍权限、多语言、内容版本、SEO、缓存、安全等坑。
直接用 FeehiCMS 或 Yii2CMS 而不是重造轮子
FeehiCMS 和 Yii2CMS 都是已稳定运行多年、生产环境验证过的 Yii2-CMS 方案,不是玩具项目:
-
FeehiCMS基于yii2-app-advanced,自带RBAC、RESTful API、操作日志、多语言和 SQLite/MySQL/PostgreSQL 三套数据库支持,Docker 一键启动就能跑后台 -
Yii2CMS(如 kzeng 版)结构更轻量,适合二次开发,git clone后执行php init+php yii migrate即可启用,前端路由和后台入口分离明确 - 二者都遵循 Yii2 标准目录结构,
Gii生成器、ActiveRecord、behaviors、events等机制完全可用,改起来不撕裂原有逻辑
别碰“单表多列”式多语言设计
很多新手在扩展文章模型时,直接加 title_zh、title_en 字段,短期省事,长期必翻车:
- 新增语言要改表结构,
ALTER TABLE在生产环境风险高 - 无法动态增删语言,
language变成硬编码字段名,Yii::$app->language失效 - 搜索、排序、全文索引无法跨语言统一处理,
LIKE查询写法爆炸增长 - 正确做法是用关联表,例如
article主表 +article_i18n翻译表,通过hasOne()关联,配合i18n组件自动切换语言上下文
后台路由和权限必须拆开管,别混 frontend/backend
Yii2-CMS 的典型错误是把后台入口塞进 frontend/web,或用简单 if 判断角色跳转:
-
backend/web/index.php必须独立部署,Nginx/Apache 配置里严格限制访问 IP 或登录态,不能靠 PHP 层拦截 -
auth_item表里的type = 1(角色)和type = 2(权限项)要分清,比如post/update是权限项,editor是角色,别把权限直接赋给用户 -
as access行为绑定到Controller类,而不是每个 action 写if (!Yii::$app->user->can('xxx')),否则漏一个就裸奔 - 菜单渲染必须走
MenuHelper::getAssignedMenu()这类基于 RBAC 的动态生成,静态数组会绕过权限校验
上传和富文本千万别自己写存储逻辑
图片上传路径、缩略图生成、富文本中图片引用、CDN 同步——这些看似简单,实则涉及文件系统、URL 生成、缓存失效、XSS 过滤多个层面:
- 用
yii\imagine\Image或intervention/image做缩略图,别用 GD 原生函数手动拼路径 - 富文本内容入库前必须过
HtmlPurifier,否则<script></script>直接进数据库;出库渲染时用Html::encode()或白名单过滤,别信strip_tags() - 上传路径别写死
/uploads/,用@webroot/uploads+@web/uploads组合,避免 Nginx 静态文件配置错位导致 403 - CDN 场景下,
AssetBundle的baseUrl要动态设为 CDN 域名,否则 JS/CSS 404,而用户上传图片 URL 要单独走Yii::$app->params['uploadUrl']
authManager 缓存导致权限不生效、富文本粘贴 Word 内容带不可见字符引发 MySQL 严格模式报错。这些都不是文档能写全的,得靠已有 CMS 的 issue 记录和测试用例兜底。











