|
《php敏捷开发框架codeigniter》一书中单独有一章,第13章《快捷的 CRUD 及其配合使用》,讲到了crud在开发中的便捷之处。
crud说白了就是将数据库的增删改和查询封装成了一个类,这样你在控制器中调用了这个类后,只须简单的写几句话就可以完成数据库操作。可能很多人在做开发的时候把每张数据表单独写了一个model,然后在控制器中调用,其实我们细细想来,这些若干的model中有许多部分是相同的,或者说是相似的。我们就是把这些相类似的操作封装成一个类,这样就大大节省了我们的代码量,而且它还是可复用的,易于维护的。
在看了原书中crud的实现方法后,发现它还是有缺陷的,首先要是使用原作者的crud类,那么主键必须是数字,虽然大部分数据设计中主键都是选择id之类的字段,但我们也不能将非数字类型的数据表拒之门外,这太武断了;其次,数组的添加和修改的操作中,原作者寄希望于通过post来传递数据,那么我们就可能考虑到,有些数据并不是通过客户端提供的,比如说一篇文章的发表时间,我们肯定是要在服务器端取,虽然我们也可以在客户端生成数据,然后post过来,但是你能保证客户端的时间跟服务器同步吗;还有有时候我们要操作的并不仅仅是一张表,例如我们要通过一个控制器修改一个学生的信息,学生的信息保存在一张表中,然后学生表中有一个学校id的外键,对应学校这张数据表,我们必须同时查询两种表,一次是查询这个学生的信息,一次是查询所有学校的学校名和学校ID,而原作者给出的代码只能在一个控制中调用一次crud,操作一张表,这显然不是我们想看到的。
对于第一个问题,我在函数中专门设定了主键类型的检查。对于第二个问题在使用post的基础上,我还另外写了一个使用数组传递数据的操作函数。对于第三个问题,我选择了使用构造函数__construct和析构函数__destruct(),进行保护现场。
下面是代码:
my crud.7z
(3.72 KB, 下载次数: 129)
按照MVC的思想,我们要把数据的操作封装在M层中,因此我们按照在model中调用crud,把数据返回给cotronller的思路,进行设计。
下面摘录部分代码,进行分析:
article_manage.php的部分代码
PHP复制代码 <?php
class Article_manage extends Model {
private $CI;
private $table = 'jx_article';
private $key = 'aid';
private $channelTable = 'jx_channel';
private $memberTable = 'jx_member';
private $commentTable = 'jx_comment';
private $adminTable = 'jx_admin';
private $childrenChannel = array();
public function __construct () {
parent ::Model();
$this->load->library('codestr');
$this->CI = & get_instance ();
$this->CI->load->model('crud');
$this->CI->crud->Crud($this->table,$this->key);
}
/**
* getOne
*
* 返回一篇文章内容
*
* @param int $aid 文章ID
* @return array $article 文章详细内容信息
*
**/
public function getOne ($aid,$decode=true,$conditions = array(),$returnCname = false) {
//$article = $this->CI->crud->getOne(array(),$aid);
if(count($conditions)>0) {
$article = $this->CI->crud->getOne($conditions);
} else {
$article = $this->CI->crud->getOneByKey($aid);
}
if(is_null($article)) return null;
if($decode==true) {
$article['title'] = $this->codestr->unescape($article['title']);
$article['content'] = $this->codestr->unescape($article['content']);
}
if($returnCname==true) {
$article['cname'] = $this->getChannel($article['f_cid']);
}
return $article;
}
/**
* insertOrUpdate
*
* 插入或者修改
*
* @param array $article 文章的详细内容
* @return int $result 影响的行数
**/
public function insertOrUpdate ($article) {
$result = $this->CI->crud->insertFromArray($article);
return $result;
}
/**
* delete
* 删除一篇文章
*
* @param int $aid 文章ID
* @return int $result 影响行数
**/
public function delete ($aid) {
$result = $this->CI->crud->delete($aid);
return $result;
}
//……省略N多的代码
/**
* __destruct
*
* 销毁当前成员变量,恢复以前成员变量(恢复现场)
*
* @param null
* @return null
**/
public function __destruct () {
$this->CI->crud->__destruct ();
} 复制代码
article.php
PHP复制代码 <?php
class Article extends MY_Controller {
public function __construct () {
parent ::__construct ();
$this->load->model('article_manage');
$this->load->library('class_post');
$this->load->library('pagination');
}
public function index () {
}
/**
* getChannel
*
* 返回所有栏目,每个栏目都有ID
* @return array 栏目数组
**/
private function getChannel () {
$this->load->model('channel');
$this->channel->__construct ();
//$channels = $this->channel->show_channel_as_select();
$channels = $this->channel->show_channel_as_select_for_lanmu();
$this->channel->__destruct ();
//echo $channels;
return $channels;
}
private function getChannel2 () {
$this->load->model('channel');
$this->channel->__construct ();
$channels = $this->channel->show_channel_as_select();
$this->channel->__destruct ();
//echo $channels;
return $channels;
}
public function add () {
//$channels = $this->article_manage->showAllChannel();
$t = '文章添加';
$data = array('t' => $t,'action' => 'add','channels' => $this->getChannel2());
//print_r($data);
$this->load->view('admin/article',$data);
}
public function addDeal () {
$this->load->library('unit_test');
$title = $this->input->post('title',true);
if($title=='') {
echo 'error,标题不能为空';
return false;
}
$content = $this->input->post('content');
if($content=='%3Cp%3E%3Cbr%3E%3C/p%3E'||$content=='%3CP%3E%3C/P%3E') {
echo 'error,内容不能为空';
return false;
}
$tcolor = $this->input->post('tcolor',true);//
if($this->class_post->fun_char(3,7,$tcolor)==false) {
echo 'error,非法传参tcolor';
return false;
}
$f_cid = $this->input->post('channel',true);//
if($this->class_post->fun_num($f_cid)==false) {
echo 'error,非法传参channel';
return false;
}
$author = $this->input->post('author',true);//
$f_uid = $this->input->post('uid',true);
if($this->class_post->fun_num($f_uid)==false) {
echo 'error,非法传参uid';
return false;
}
$source = $this->input->post('source',true);
$istop = $this->input->post('top',true);//
if($this->class_post->fun_num($istop)==false) {
echo 'error,非法传参top';
return false;
}
$recommend = $this->input->post('levels',true);//
if($this->class_post->fun_num($recommend)==false) {
echo 'error,非法传参levels';
return false;
}
$cancomment = $this->input->post('comment',true);//
if($this->class_post->fun_num($cancomment)==false) {
echo 'error,非法传参comment';
return false;
}
date_default_timezone_set("PRC");
$date = date('Y-m-d');
$data = array (
'title' => $title,
'tcolor' => $tcolor,
'f_cid' => $f_cid,
'author' => $author,
'f_uid' => $f_uid,
'source' => $source,
'istop' => $istop,
'recommend' => $recommend,
'cancomment' => $cancomment,
'time' => $date,
'content' => $content
);
$result = $this->article_manage->insertOrUpdate($data);
if(is_null($result)||(isset($result['affected'])&&$result['affected']<=0)) {
echo 'error,添加失败';
} else {
echo '添加成功';
}
//$this->output->enable_profiler(true);
}
//……在此省略N多的代码 复制代码
注意我们在article这个控制器中调用了两个crud的实例,其中一此调用是在getChannel2()中,记得在这个函数中使用$this->channel->__construct();和$this->channel->__destruct();这两步起到了保护现场的作用。 |
评分
-
查看全部评分
|