Heim > Fragen und Antworten > Hauptteil
Verwenden Sie ThinkPhp3.2 für die Entwicklung, da wir häufig Hinzufügungs-, Lösch-, Änderungs- und Suchvorgänge verwenden müssen, um die Wiederverwendung von Code zu erhöhen. Ich habe curdControler und curdModel gemeinsam geschrieben, um das Hinzufügen, Löschen, Ändern und Abfragen des Codes durchzuführen. Wenn ich das Hinzufügen, Löschen, Ändern und Abfragen verwenden muss, erbe ich curdController und curdModel direkt.
Jetzt gibt es ein Problem. Generell erfordert die Quarkoperation eine Genehmigung, sonst wird es sehr gefährlich. Meine Idee hier ist, checkAuth() in der curdController-Konstruktionsmethode aufzurufen. Aufgrund verschiedener Funktionen sind die Methoden der Berechtigungskontrolle unterschiedlich. Wie kann man Unterklassen, die curdController erben, dazu zwingen, die checkAuth-Methode zu überladen?
Meine Idee ist, dass ich die Berechtigungsbeurteilungsfunktion als abstrakte Methode definiere
protected abstract function checkAuth()
Die Klasse curdController ist als abstrakte Klasse definiert, aber wenn die abstrakte Klasse nicht instanziiert werden kann, ist der Code des Konstruktors ungültig. Was ist an dieser Implementierung falsch?
Zweite Frage: Haben Sie bessere Ideen für die Wiederverwendung von TP-Code? Was sind die versteckten Gefahren und Probleme meines Ansatzes? Vielen Dank für Ihren Rat.
class CurdController extends Controller
{
//基础curd类必须进行权限判断,否则会造成很大的问题
public function __construct()
{
parent::__construct();
$this->checkAuth();
}
//存储模型对象
protected $_model;
//权限判断函数
protected function checkAuth(){}
//列表处理函数
public function listC(){
// 列表前置函数
$this->beforeList();
$data=$this->_model->lists();
$this->assign('lists',$data);
$this->display();
}
public function delC(){
$id=intval(I('get.id'));
$where['id']=$id;
$res=$this->_model->del($where);
$this->redirectUrl($res,'listC');
}
public function addC(){
// 添加前置函数
$this->beforeAdd();
if(IS_POST){
$data=I('post.');
$res=$this->_model->Store($data);
$this->redirectUrl($res,'listC');
}
$this->display();
}
public function editC(){
$id=intval(I('get.id'));
//where的数组形式
$where['id']=$id;
// 编辑前置函数
$this->beforeEdit($where);
if(IS_POST){
$where=I('post.');
$where['id']=$id;
$res=$this->_model->Store($where);
$this->redirectUrl($res,'listC');
}
$this->display();
}
//列表前置操作
protected function beforeList(){
}
/**
* 添加控制器前置操作
*/
protected function beforeAdd(){
}
/**
* 编辑控制器前置操作
* @param $where
*/
protected function beforeEdit($where){
}
typecho2017-07-01 09:13:50
代码复用,我建议用PHP的特性:
http://php.net/manual/zh/lang...
或者用闭包绑定(不太推荐):
http://php.net/manual/en/clos...
checkAuth
可以通过不同的业务,书写不同的traits,在具体继承curdController的类中使用对应的traits,由于checkAuth()
只返回校验结果的真假,所以这个可以向任意的Controller中定制checkAuth()
。
针对你的第一个问题,由于你在继承了抽象类curdController
的子类构造函数里,手动调用了parent::__construct();
,只要子类被实例化,父类的构造函数也是可以用的,看下面例子:
代码:
<?php
abstract class A
{
public function __construct()
{
echo '父类';
}
}
class B extends A
{
public function __construct()
{
parent::__construct();
echo '子类';
}
}
$test = new B();
结果:
针对你第二个问题,个人觉得整个结构框架有些粗,对于常见的一对多和多对多关系仍然需要手动去做,建议将这种关联操作也封装起来。
虽然我个人用的比较多的框架是CodeIgniter
,但是我觉得MVC(HMVC)模型基本思路都是一致的,所以下面谈下我个人在CodeIgniter
里做的重用封装:
我个人将数据表的原子操作放在了底层Model
上面(是基于CI-Base-Model
改的,你可以看一下CI-Base-Model
里的has_many
和belongs_to
配置),另外我继承了CI-Base-Model
自己写了一个CRUD_Model
,这个CRUD_Model
中,几乎靠一些配置项和一些重写,就可以快速生成一个标准CRUD数组,下面可以放出部分源码:
<?php
/**
* @uses array_helper
*/
class CRUD_Model extends CI_Base_Model
{
public $ci;
public $crud_total = 0;
private $crud_offset = 0;
private $crud_page = 0;
private $crud_limit = 20;
protected $crud_mask = [];
public $crud_id = [];
public $crud_user_id = 0;
public $crud_time = 0;
public $crud_time_str = '';
public $crud_error_code = 0;
public $crud_has_error = FALSE;
public function __construct()
{
parent::__construct();
$this->ci = &get_instance();
}
/**
* ---------------------------------------------------------
* CRUD Block-separated Methods
* CRUD 子功能方法
* ---------------------------------------------------------
*/
public function crud_paginator($offset = NULL, $page = NULL, $limit = 20)
{
// 解析分页参数的方法
...
}
public function crud_set_error($error_code = 0)
{
// 设置错误码(用于API或者Controller判定)和错误标记的方法
$this->crud_has_error = TRUE;
$this->crud_error_code = $error_code;
}
protected function crud_process_id($id = 0, $data = [])
{
// 处理ID并缓存的方法
...
}
protected function crud_prepare($data = [])
{
// 准备数据(时间戳之类后面需要用到但和主体关系不大的数据)的方法
$this->crud_time = time();
$this->crud_time_str = date('Y-m-d H:i:s', $this->crud_time);
}
protected function crud_filter_fields($data = [])
{
// 添加和修改时,过滤原数据中不需要的字段的方法
...
}
protected function crud_save_total($data = [])
{
// 查询加上过滤条件后的总条数的方法
$this->select("''");
$this->crud_total = $this->count_all_results();
}
protected function crud_add_list_filter($data = [])
{
// 列表筛选条件过滤方法
}
protected function crud_add_detail_filter($data = [])
{
// 详情筛选条件过滤方法
}
protected function crud_add_fields($data = [])
{
// 列表和详情字段附加方法(SELECT子句)
}
protected function crud_add_limit()
{
// 条数限制(分页过滤器)方法
if($this->crud_limit !== 'all') {
$this->limit($this->crud_limit, $this->crud_offset);
}
}
protected function crud_add_order($data = [])
{
// 排序附加方法
}
protected function crud_add_list_with($data = [])
{
// 列表with(CI-Base-Model中额外添加数据的绑定钩子)的附加方法
}
protected function crud_add_detail_with($data = [])
{
// 详情with的附加方法
}
protected function crud_build_item($item = [])
{
// 对列表和详情字段进行处理的方法(直接取出来默认是字符串,如果是数字型需要手动转)
return $item;
}
protected function crud_build_proto($data = [])
{
// 构造列表分页输出结构的方法,这个之后会向这个数组再附加列表list值
$proto = [];
$proto['total'] = ...;
$proto['offset'] = ...;
$proto['page'] = ...;
$proto['is_last_page'] = ...;
$proto['is_full_page'] = ...;
return $proto;
}
protected function crud_detail_precheck($detail = [])
{
// 详情预检查方法
return TRUE;
}
protected function crud_detail_postcheck($detail = [])
{
// 详情后期检查方法
return TRUE;
}
protected function crud_insert_precheck($data = [])
{
// 新增预检查方法
return TRUE;
}
protected function crud_insert_postcheck($data = [])
{
// 新增后期检查方法
return TRUE;
}
protected function crud_update_precheck($data = [])
{
// 更新预检查方法
return TRUE;
}
protected function crud_update_postcheck($data = [])
{
// 更新后期检查方法
return TRUE;
}
protected function crud_delete_precheck($data = [])
{
// 删除预检查方法
return TRUE;
}
protected function crud_delete_postcheck($data = [])
{
// 删除后期检查方法
return TRUE;
}
protected function crud_insert_rebuild($data = [])
{
// 新增数据时重新构造传入数据的方法(使其符合数据库结构)
return [];
}
protected function crud_update_rebuild($data = [])
{
// 更新数据时重新构造传入数据的方法
return [];
}
/**
* ---------------------------------------------------------
* CRUD Main Methods
* CRUD 主要函数
* ---------------------------------------------------------
*/
protected function crud_list($offset = NULL, $page = NULL, $limit = 20, $data = [])
{
// 查询列表
...
}
protected function crud_detail($id = 0, $data = [])
{
// 查询详情
...
}
protected function crud_insert($data = [])
{
// 添加
...
}
protected function update_feed($id = 0, $data = [])
{
// 修改
...
}
protected function crud_delete($id = 0)
{
// 删除
...
}
}
我这个模型的思路希望可以对你细化CRUD逻辑有所帮助。