wellcms 主程序架构采用函数风格的 MVC,插件机制采用 AOP 机制,面向切面编程,也就是往代码里插入代码,合并后再执行(合并后的代码存放于 tmp 目录下),使得性能方面零损耗,不影响编译,强大而又简单。大大的简化了程序的复杂度,在同等复杂度的功能实现上比同类产品的代码简洁很多,核心只有 22 个表,非常利于二次开发。
wellcms程序结构:
index.php 入口程序
conf/ 配置文件目录
lang/ 语言包
log/ 日志目录
tmp/ 临时目录
model/ 数据调用(复用度高)
route/ 业务逻辑(复用度低)
plugin/ 插件目录
upload/ 上传文件
view/ 模板、静态资源(js, css, img, htm, font)
xiunophp/ 公共的函数库
admin/ 后台管理
开发插件前 打开 index.php,修改 DEBUG 为 2 (这样可以及时看到效果,上线后还原为 0)
!defined('DEBUG') AND define('DEBUG', 2);
插件依赖 conf.json 文件:
{ "name": "插件名", "brief": "插件介绍", "version": "1.0.0", // 插件版本 "software_version": "2.0.0", "type": 0, "installed": 0, // 0卸载 1安装 "enable": 0, // 0禁用 1启用 "hooks_rank": [], // 最大值优先 hook 可以同时设置多个文件优先 hook 对应的数值越大越会被优先使用 "overwrites_rank": [], // 仅限最大值 overwrite 一次,可同时设置多个文件优先 overwrite 对应的数值越大越会被优先使用 "dependencies": [] // 依赖其他插件 }
具体开发请看 hook功能 或 overwrite
插件目录命名约束:开发者英文前缀 + 功能,由下划线“_”分割,比如 well_random
插件配置信息,统一使用
setting_set('key', 'value');setting_get('key');setting_delete('key');
插件开发数据表约束:
一、表和字段命名、自定义方法、声明数组、变量、以及 css 定义class 和 id,包括表单,不管是 php 还是 js 还是 html ,命名务必使用 唯一前缀_单词(下划线"_"分割) 不要使用拼音;
well_alias 所有需要声明定义的,必须加唯一前缀,错误时方便排查,也避免冲突。
$well_arr = array('well_title' => 'This is title');$well_title = $well_arr['well_title'];// 定义方法function well_thread_create($arr) { // .....}
css 定义
.well_alias{}#well_alias{}
<div class="well-text-red" id="well_order"> HTML</div><script>var well_data = [];</script>
二、以下3个表禁止创建其他索引,如需增加索引,请在附表创建,或者新建表。创建索引前,请先灌100万数据进行测试,在 mysql 使用 explain 看是否走了创建的索引,以免创建无意义的索引。索引以左优先原则创建。
website_thread website_data website_comment
1.禁止使用未建索引的查询;
2.使用 int、tinyint 类型建立有效索引,尽量少使用或不使用 char 或 varchar 类型建立索引;
3.禁止在状态 status 字段上建立索引,因为在海量数据下筛选为数不多的数据,得不偿失;
4.禁止使用索引类型 UNIQUE 所有业务逻辑在程序中完成;
5.禁止在 mysql 做运算查询,如 where views>10 或 group by 之类,尽可能避免在 where 语句中使用 != 或者 <> 操作符,因为,查询引用会放弃索引进行全表扫描。实践表明高负载环境,数据库使用场景越简单越好,最好的结果就是所有查询语句除了 where 没其他;
6.禁止在非索引的字段进行查询;
7.禁止使用连表查询;
8.禁止使用非主键统计语句;
9.禁止在以下几个表建立非 tinyint 或 int 类型的字段;
website_comment_pid website_thread_tid website_flag_thread website_tag_thread
10.查询、修改、删除尽可能的使用主键;
11.查询 SELECT * 不写字段,一次查完;
12.order by 必须建立在索引之上;
13.禁止使用日期类型的字段DATE\DATETIME之类,所有日期类型一律使用int,储存为时间戳或数字串如20200113;
14.字段储存尽量设计为使用tinyint或int,能用tinyint就不用int,能用int就不用bigint。能用tinyint代替char和varchar就代替,比如很多人喜欢直接用“男”“女”储存性别,可以直接用tinyint(1),储存值0无性别 1男 2女 这种形式;
15.创建字段默认值禁止使用“无”或 “NULL”,数字型字段一律默认值0,字符类型一律空。
16.很少使用的大字段拆分到单独表,如wellcms的内容详情,使用单独的data表,因为,绝大部分的操作都以标题为主;
17.封装 SQL 语句不能任性写,必须依照现有的索引左优先原则,创建索引前请设计好,不能 where `uid`='1' and `tid`=`1` 然后高兴就又写成 where `tid`=`1` and `uid`='1' 如果你这样玩,我会喷到你体无完肤。索引是什么顺序,语句必须保持一致。
18.所有内容主题类的请求数据,一律查询主键后扔进官方统一拉取数据的函数,统一获取数据,避免多次查询同一个表,wellcms 所有的操作,只对同一个表查询一次,不管有什么花样的数据调用,任何页面的数据,每个表只能查询一次,这是原则,不能改变。wellcms 不管是门户模式,还是扁平模式,所有表只查询一次。因为 wellcms 是专为大数据量、高并发网站设计的架构。同一个页面查询同一个表 N 次,还谈什么数据承载量和高并发,这就是笑话。
<1>列表类统一拉取,避免多次查询thread表 thread_unified_pull($arr) 具体二开请自行查看该函数如何使用;
<2>详情页其他主题调用,集合tid统一拉取数据 thread_other_pull($thread) 具体二开请自行查看该函数如何使用;
19.单一查询适当使用 cache ,用户类数据一律永久缓存,标题类一律缓存生命期7200秒,内容详情类一律缓存生命期3600秒或1800秒,更新数据记得清理缓存cache_delete 或者直接 cache_update 更新缓存数据(具体使用请查看相关函数),避免再次到SQL获取,对于一直动态变化的数据没必要使用缓存,如列表。
20.不要问为什么,听话照做,不进坑。
字段类型使用约束:
尽可能的使用 tinyint 或 int
hook 代码的 php 文件 ( 仅限于 php 文件 ),请使用下面的方式,开头必须加上 exit; 目的是以防文件运行,影响安全。
例如 index_inc.php 这个文件有个 index_inc_after.php 钩子,那么,hook这个地方的文件命名 index_inc_after.php 代码如下
<?php exit;$route = param(0, 'list'); /* 其他业务代码 */?>
htm 文件加载css和js文件,插件全部采用异步加载:
异步加载 js, 加载成功以后 callback
$.require(... callback)
...: js 文件的URL
callback: 最后一个参数为回调函数
<script type="text/javascript"> var well_js_path = '<?php echo $conf['path'];?>'; $.require(well_js_path+'1.js', well_js_path+'2.js', function() { alert('after all loaded'); });</script>
无需回调的直接加载
<script type="text/javascript"> $.require('<?php echo $conf['path'];?>plugin/huux_tinymce/prism/prism.js');</script>
异步加载 css
<script type="text/javascript"> var well_js_path = '<?php echo $conf['path'];?>'; $.require(well_js_path+'1.css');</script>
希望以上内容对你有所帮助!如果还有其他问题,请随时提问。 各类知识收集 拥有多年CMS企业建站经验,对 iCMS, Fastadmin, ClassCMS, LeCMS, PbootCMS, PHPCMS, 易优CMS, YzmCMS, 讯睿CMS, 极致CMS, Wordpress, HkCMS, YznCMS, WellCMS, ThinkCMF, 等各类cms的相互转化,程序开发,网站制作,bug修复,程序杀毒,插件定制都可以提供最佳解决方案。