ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 1\. 框架 ## 1.1. 引言 1. 定义及缩略语 | key | value | | --- | --- | | Zero框架 | 提供框架、公共基础组件、公共业务组件加速业务的日常研发工作 | 2. 目的 本规范由编程原则组成,融合并提炼了开发人员长时间积累下来的成熟经验,意在帮助形成良好一致的编程风格。以达到事半功倍的效果,如果有需要本文档会不定期更新。 3. 适用范围 如无特殊说明,以下规则要求完全适用于基于Zero框架框架开发的应用,同时也可大部分适用于部门其他PHP项目。 4. 标准化作用 当一个软件项目尝试着遵守公共一致的标准时,可以使参与项目的开发人员更容易了解项目中的代码、弄清程序的状况。使新的参与者可以很快的适应环境,防止部分参与者出于节省时间的需要,自创一套风格并养成终生的习惯,导致其它人在阅读时浪费过多的时间和精力。而且在一致的环境下,也可以减少编码出错的机会。 缺陷是由于每个人的标准不同,所以需要一段时间来适应和改变自己的编码风格,暂时性的降底了工作效率。从使项目长远健康的发展以及后期更高的团队工作效率来考虑暂时的工作效率降低是值得的,也是必须要经过的一个过程。标准不是项目成功的关键,但可以帮助我们在团队协作中有更高的效率并且更加顺利的完成既定的任务。 1) 程序员可以了解任何代码,弄清程序的状况 2) 新人可以很快的适应环境 3) 防止新接触PHP的开发出于节省时间的需要,自创一套风格并养成终生的习惯 4) 防止新接触PHP的开发一次次的犯同样的错误 5) 在一致的环境下,可以减少犯错的机会 ## 1.2. 目录结构规范 ### 1.2.1. 框架路径 ### 1.2.2. 应用目录结构 #### 1.2.2.1. 配置configs 存放配置文件 默认$\_GET变量经过了 htmlspecialchars #### 1.2.2.2. 公用类库 libraries 框架及公用类库,不允许修改 #### 1.2.2.3. 控制器controllers 所有控制器都继承Controller, 类名以Ctl结尾, 写法如下: 例如控制器 /$app\_name/controllers/IndexCtl.php ~~~php <?php class IndexCtl extends Zero_Controller { public function __construct(&$ctl, $met, $typ) { parent::__construct($ctl, $met, $typ); } public function test() { $this->render('default'); /* $this->render('default', $data, $msg, $status); $this->render($name='default', $data=array(), $msg='success', $status=200) */ /** * @param string $name layoutname, 对应文件在views/layouts/{$name}.php * @param array $data 渲染数据 * @param string $msg 消息提示 * @param int $status 状态 */ } } ?> ~~~ #### 1.2.2.4. 模型models 模型 每一个表都对应的一个模型, 例如user\_base 表 对应的模型为 /models/User/BaseModel.php , 对表user\_base的操作,必须经过 User\_BaseModel. ~~~php <?php if (!defined('ROOT_PATH')) exit('No Permission'); /** * 用户基本信息模型 * * @category Framework * @package Model * @copyright Copyright (c) 2016-10-14 * @version 1.0 * @todo */ class User_BaseModel extends Zero_Model { public $_cacheName = 'user'; public $_tableName = 'user_base'; public $_tablePrimaryKey = 'user_id'; public $_useCache = false; //代表存入数据库的数据格式, DOT为英文逗号分割 public $fieldType = array('user_state'=>'DOT', 'user_json'=>'JSON', 'user_html'=>'HTML'); /** * 默认key = $this->_tableName . '_cond' * @access public */ public $_multiCond = array( 'user_base_cond'=>array( 'user_account'=>null, 'user_token'=>null, ) ); public $_validateRules = array('integer'=>array('user_id', 'user_state')); public $_validateLabels= array(); /** * @param string $user User Object * @var string $db_id 指定需要连接的数据库Id * @return void */ public function __construct(&$db_id='account', &$user=null) { $this->_useCache = CHE; $this->_tabelPrefix = TABLE_ACCOUNT_PREFIX; parent::__construct($db_id, $user); } /** * 读取分页列表 * * @param array $column_row where查询条件 * @param array $sort 排序条件order by * @param int $page 当前页码 * @param int $rows 每页显示记录数 * @return array $data 返回的查询内容 * @access public */ public function getLists($column_row=array(), $sort=array(), $page=1, $rows=500) { //修改值 $column_row $data = $this->lists($column_row, $sort, $page, $rows); return $data; } } ?> ~~~ 模型中可用方法: ~~~php <?php add //insert, 可以传入二维数据一次添加多条记录 save //保存内容,insert|update , 可以传入二维数据一次添加或者编辑多条记录, 如果有主键则编辑,否则添加 remove removeCond //根据条件删除操作 edit editInc //是否增量更新 edit 别名 editCond //根据条件edit操作 get getOne getFoundRows lists //根据条件读取分页列表 listKey find //根据条件读取列表 findOne findKey //查找主键 $_tableName 决定了这个模型操作表 user_base /** * 插入 - 可以传入二维数据一次添加多条记录 插入多条记录 实现批量插入数据 * @param array $field_row 信息 * @param bool $return_insert_id 是否返回自增主键 * @param bool $replace 是否数据覆盖 * @return bool 是否成功 * @access public */ public function add($field_row, $return_insert_id=false, $replace=false) { } /** * 保存内容,insert|update 可以传入二维数据一次添加或者编辑多条记录, 如果有主键则编辑,否则添加 * @param array $field_row key=>value数组 * @param bool $return_insert_id 自增主键 * @param bool $flag 是否增量更新 * @return bool $update_flag 是否成功 * @access public */ public function save($field_rows, $return_insert_id=false, $flag=false) { } /** * 传入主键删除操作 * @param mix $table_primary_key_value * @return bool $del_flag 是否成功 * @access public */ public function remove($table_primary_key_value) { } /** * 根据条件删除操作, 如果存在主键,使用remove * @param mix $table_primary_key_value * @return bool $del_flag 是否成功 * @access public */ public function removeCond($column_row=array()) { } /** * 根据主键更新表内容 * @param mix $table_primary_key_value 主键 * @param array $field_row key=>value数组 * @param bool $flag 是否增量更新 * @param array $field_old_row key=>value数组 * @return bool $update_flag 是否成功 * @access public */ public function edit($table_primary_key_value=null, $field_row, $flag=null, $field_old_row=null) { } /** * 是否增量更新 edit 别名 * @param mix $table_primary_key_value * @param array $field_value_new * @param array $field_value_old * @return bool $update_flag 是否成功 * @access public */ public function editInc($table_primary_key_value=null, $field_row, $field_old_row=null) { } /** * 根据条件更新表内容 * * @param array $column_row 条件 * @param array $field_row key=>value数组 * @param bool $flag 是否增量更新 * @param array $field_old_row key=>value数组 * @return bool $update_flag 是否成功 * @access public */ public function editCond($column_row=array(), $field_row, $inc_flag=null, $field_old_row=null) { } /** * 只获取一条记录 * * @param int $table_primary_key_value 主键值 * @return array $rows 返回的查询内容 * @access public */ public function getOne($table_primary_key_value=null, $key_row=null, $sort_row=array()) { $row = array(); $rows = $this->get($table_primary_key_value, $key_row, $sort_row); if ($rows) { $row = reset($rows); } return $row; } /** * 根据主键值,从数据库读取数据, 必须获取主键后再读取数据 * * @param int $table_primary_key_value 主键值 * @return array $rows 返回的查询内容 * @access public */ public function get($table_primary_key_value=null, $key_row=null, $sort_row=array()) { } /** * 取得影响的行数 * * @return int $num 行数 * @access public */ public function getFoundRows() { $num = $this->_selectFoundRows(); return $num; } /** * 获取数据记录行数, cache 清除太多,不合理. 组名称,是否根据用户id来处理.特列下允许使用, 正常通过数据库来存储冗余统计数据 * * @param array $cond_row * @param string $group * @param bool $cache_flag 是否启用cache * @return int * @access public */ public function getNum($cond_row, $group=null, $cache_flag=false) { } /** * 读取分页列表, find根据条件获取数据, 而get根据id获取数据 * * @param int $column_row where查询条件, 需要设置在multiCond中, 方便处理为group名字,用来通过组更新缓存 * @param string $group 组名称 * @param int $page 当前页码 * @param int $rows 每页显示记录数 * @param int $sort_row 排序方式 * @return array $rows 返回的查询内容 * @access public */ public function find($column_row=array(), $sort_row=array(), $page=1, $page_num=500, $group=null, $cache_flag=false) { } public function findOne($column_row=array(), $sort_row=array(), $page=1, $page_num=1, $group=null, $cache_flag=false) { } /** * 根据where条件取得主键 * * @param array $cond_row * @param array $sort_row * @param int $page * @param string $group * @param bool $cache_flag * @return array $rows 信息 * @access public */ public function findKey($cond_row=array(), $sort_row=array(), $page=1, $page_num=500, $group=null, &$total=0, $cache_flag=false) { } /** * 读取分页列表Id * * @param int $column_row where查询条件, 需要设置在multiCond中 * @param int $sort_row array('key'=>'ASC|DESC')排序方式 * @param int $page 当前页码 * @param int $rows 每页显示记录数 * @param string $group 组名称 * @param bool $cache_flag 是否缓存 * @param bool $array_flag 是否使用array_value处理返回的items * @return array $rows 返回的查询内容 * @access public */ public function listKey($column_row=array(), $sort_row=array(), $page=1, $page_num=500, $group=null, $cache_flag=false, $array_flag=true) { $data = array(); $data['page'] = $page; $data['total'] = $total; //total page $data['records'] = $records; $data['items'] = $array_flag ? array_values($data['items']) : $data['items']; return $data; } /** * 读取分页列表 * * @param int $column_row where查询条件, 需要设置在multiCond中, 方便处理为group名字 * @param int $sort_row 排序方式 * @param int $page 当前页码 * @param int $rows 每页显示记录数 * @param string $group 组名称 * @param bool $cache_flag 是否缓存 * @param bool $array_flag 是否使用array_value处理返回的items * @return array $rows 返回的查询内容 * @access public */ public function lists($column_row=array(), $sort_row=array(), $page=1, $page_num=500, $group=null, $cache_flag=false, $array_flag=true) { $data = array(); $data['page'] = $page; $data['total'] = ceil_r($total / $page_num); //total page $data['records'] = $total; $data['items'] = $array_flag ? array_values($data['items']) : $data['items']; return $data; } ?> ~~~ #### 1.2.2.5. 视图views 例如控制器 /$app\_name/controllers/IndexCtl.php中, test方法,$this->render('default'); 会调用到文件/$app\_name/views/default/layouts/default.php /$app\_name/views/default/IndexCtl/test.php #### 1.2.2.6. 路由规则 默认入口文件为index.php, 例如请求URL为 /index.php?ctl=Index&met=test 程序会运行文件 /$app\_name/controllers/IndexCtl.php 中 Class 为 IndexCtl 中的 test 方法. ### 1.2.3. 前端要求 #### 1.2.3.1. 不得随意构造URL, 必须通过配置来调用URL, 见config.js #### 1.2.3.2. pjax data-pjax="#page-container" lazyload fancybox tips