用户
 找回密码
 入住 CI 中国社区
搜索
查看: 13168|回复: 16
收起左侧

[模型] CI 根据url 自动where 自动分页 (基于BackendPro)

    [复制链接]
发表于 2010-5-20 11:55:48 | 显示全部楼层 |阅读模式
本帖最后由 myzingy 于 2010-5-20 11:59 编辑

提要:关于BackendPro(用了你会发现它是非常棒的,你不用在处理用户及权限)  http://codeigniter.org.cn/forums/thread-1264-1-1.html
介绍:BackendPro 是一个为 CodeIgniter 开发者设计的控制台,不是像 CMS 般提供现成的系统,它只提供系统的一部份。它提供一些会重复性使用的功能,像是认证、权限与管理介面基本的画面。使用现有的 PHP 与 CodeIgniter 知识可以藉由 BackendPro 建立完整的网站,你可以更专注在应用本身,而非一些系统管理功能。
安装:下载BackendPro 直接覆盖至CI根目录
--------------------------------------------------------------------------------------------------
正文:在写model时,我们经常要对表进行where和分页,每次重复的劳动让人难受。接触BackendPro后,发现它的Base_model中就集成了fetch,insert,update,delete四种常用方法,我们的分页和where也是和这四种一样,常用而且也是模型级别的,所以我扩展了Base_model中的方法
添加了自动where
PHP复制代码
function autowhere($fields){
                $url_param=$this->uri->uri_string();
                preg_match_all("/([a|o][eoligt]{1,2}-[a-z\.]+)\/([^\/]+)/i",$url_param,$url_xxx);//取url搜索条件
                if(!$url_xxx) return;
                $url_param=$url_xxx[1];
                $url_value=$url_xxx[2];
                $where='';
                foreach($url_value as $k=>$v){
                        if(!$v){continue;}
                        if(strpos($v,'%')!==false){
                                $v=urldecode($v);//中文转码
                        }
                        $key=$url_param[$k];
                        list($a,$b)=explode('-',$key);
                        if(!in_array($b,$fields)){continue;}
                        switch($a){//下面的语句我就不解释了,where条件很清楚
                                case "ae":
                                        $this->db->where($b,$v);
                                        $where.="\$this->db->where($b,$v);";
                                break;
                                case "oe":
                                        $this->db->or_where($b,$v);
                                        $where.="\$this->db->or_where($b,$v);";
                                break;
                                case "al":
                                        $this->db->like($b,$v);
                                        $where.="\$this->db->like($b,$v);";
                                break;
                                case "ol":
                                        $this->db->or_like($b,$v);
                                        $where.="\$this->db->or_like($b,$v);";
                                break;
                                case "ai":
                                        $v=explode(",",$v);
                                        $this->db->where_in($b,$v);
                                        $where.="\$this->db->where_in($b,$v);";
                                break;
                                case "agt":
                                        $this->db->where("$b >",$v);
                                        $where.="\$this->db->where('$b >',$v);";
                                break;
                                case "alt":
                                        $this->db->where("$b <",$v);
                                        $where.="\$this->db->where('$b <',$v);";
                                break;
                                case "oo":
                                        $this->db->order_by($b,$v);
                                        $where.="\$this->db->order_by($b,$v);";
                                break;
                        }
                }
                return empty($where)?NULL:$where;
        }
复制代码

及自动分页
PHP复制代码
function autopage($datanum,$per_page=20){
                $url_param=$this->uri->uri_string();
                preg_match("/(\/page)\/([^\/]*)/",$url_param,$page);
                $this->page=0;
                if($page){
                        if($page[2]>0){
                                $this->page=$page[2];
                        }
                        $url_param=str_replace($page[0],"",$url_param);
                }
                $this->load->library('pagination');
                $config['base_url'] = base_url()."/index.php/{$url_param}/page";
                $config['total_rows'] = $datanum;
                $config['per_page'] = $per_page;
                $config['cur_page'] = $this->page;
                $this->pagination->initialize($config);
                return $this->pagination->create_links();
        }
复制代码

--------------------------------------------------------------------------------------------------------------
然后就是在具体的模块里调用了,模块必须继承Base_model,否则无法调用到
PHP复制代码
 
class Hotel_model extends Base_model
{
        function Hotel_model()//模块初始化函数,定义初始一些数据
        {
                parent::Base_model();
                $this->lang->load('restaurantslib');
                $this->_prefix = $this->config->item('hotels_table_prefix');
                $this->_TABLES = array(
                        'U'  => $this->config->item('backendpro_table_prefix').'users',  
                        'HD' => $this->_prefix . 'data',
            'HB' => $this->_prefix . 'branch',
                        'HPF' => $this->_prefix . 'profiles',
                        'HR'=>$this->_prefix . 'recommend',//推荐
                        'HI'=>$this->_prefix . 'impression',//印象
                );
}
/**
这个就是获取酒店的函数,我将细细说明。
参数$count为true时,将会返回分页及数据,为false时只返回数据。如果只想取数据,就把此值设置为false。
*/

function get_hotels($where = NULL, $limit = array('limit' => NULL, 'offset' => ''),$count=false){
                $where_fileds=array('name','tid');//这里定义你sql语句中允许的where字段,将和url进行比对
                if( ! is_null($where))//这里的where是控制器传递过来的
                {
                        $this->db->where($where);
                }
                $autowhere=$this->autowhere($where_fileds);//调用自动where并返回一个可重用的where从句
                if($count){
                        $this->db->select('count(*)',false);
                        $this->db->from($this->_TABLES['HD']);
                        $datarows=$this->db->count_all_results();
                        $pagination=$this->autopage($datarows,$limit['limit']);//调用自动分页,直接返回分页html代码
                }
                if( ! is_null($where))//因为一次查询后,where被清除,所以必须再调用一次
                {
                        $this->db->where($where);
                }
                if($autowhere){eval($autowhere);}//把生成的where从句也执行一边,如果eval产生警告错误可用@eval($autowhere)将其屏蔽。
                $this->db->select('HD.*,U.username');
                $this->db->from($this->_TABLES['HD'] ." HD");
                $this->db->join($this->_TABLES['U'] . " U",'U.id=HD.uid','left');
                if( ! is_null($limit['limit']))
                {
                        $this->db->limit($limit['limit'],( isset($this->page)?$this->page:''));
                }
                if($count){//为true时返回数据数,分页及数据集
                        return array(
                                'datarows'=>$datarows,
                                'pagination'=>$pagination,
                                'data'=>$this->db->get()
                        );
                }
                //为false时直接返回数据集
                return $this->db->get();       
        }
}
复制代码

-----------------------------------------------------------------------------------------------------------------------
控制层中调用
PHP复制代码
function hotels(){
                $this->load->model('hotel_model');
                $data['page'] = $this->config->item('backendpro_template_admin') . "hotels";
                $data['module'] = 'restaurants';
               
                $limit=array('offset'=>NULL,'limit'=>10);
                $info=$this->hotel_model->get_hotels(NULL,$limit,true);//第一个参数可设置where(比如我们想看某个用户的酒店,就设置array('uid'=>'xx')),第二个参数设置一页显示多少条数据,第三个参数表示我需要它给我返回数据集和分页代码
                $data['info'] = $info['data'];//在前台显示的数据集
                $data['pagination']=$info['pagination'];//在前台显示的分页代码
               
                $this->load->view($this->_container,$data);
}
复制代码

---------------------------------------------------------------------------------------------------------------------
显示层代码
PHP复制代码
<ul>
<?php foreach($info->result() as $row):?>
<li><?=$row->name?></li>
</ul>
<div class="pagelist"><?php if ($pagination) print($pagination);?></div>
复制代码

-----------------------------------------------------------------------------------------------------------------------
最终实现,我们创建搜索框,js我就不写了,比如搜索酒店名中包括金花的
url格式如:http://xxx/hotels/al-name/金花                        
酒店名是金花的
http://xxx/hotels/ae-name/金花   
中文在url中是没法传递的,需要进行两次js编码 encodeURI(encodeURI(name))或php编码urlencode,一次是不行的
希望看完此文对你有帮助

评分

参与人数 1威望 +5 收起 理由
Hex + 5 我很赞同

查看全部评分

 楼主| 发表于 2010-5-20 12:51:44 | 显示全部楼层
11.JPG 33.JPG 22.JPG
 楼主| 发表于 2010-5-20 18:02:55 | 显示全部楼层
我要努力顶起,现在没在线看的效果,我提供这种实现方式,大家讨论下
发表于 2010-5-21 12:47:57 | 显示全部楼层
这个嘛,还是觉得用get方便一点:)
 楼主| 发表于 2010-5-21 15:36:58 | 显示全部楼层
本帖最后由 myzingy 于 2010-5-21 15:41 编辑

这个自动where自动分页真不是post,不正是通过url实现get的吗
如url:
http://www.***.com/BackendPro/index.php/auth/admin/members/index/al-username/7788  搜索用户名包含7788的用户
http://www.***.com/BackendPro/index.php/auth/admin/members/index/al-username/7788/page/10  搜索用户名包含7788的用户,从第10条开始显示(就是分页了,第2页)
http://www.***.com/BackendPro/index.php/auth/admin/members/index/al-username/7788/page/20  搜索用户名包含7788的用户,从第20条开始显示(就是分页了,第3页)


发表于 2010-5-21 22:13:35 | 显示全部楼层
我的意思是说原生的get,?a=x&b=x的形式
 楼主| 发表于 2010-5-24 09:02:41 | 显示全部楼层
/        不是更利于SEO吗,?a=b&c=d只是地址格式不同,我写的这个是想说我们可以根据url方式进行where和分页,地址格式都是可以互转的
发表于 2010-5-24 09:51:10 | 显示全部楼层
额,没说你这个不好啊,额,这么针锋相对哈:)
 楼主| 发表于 2010-5-24 10:02:51 | 显示全部楼层
:)(*^__^*) 嘻嘻……,多心了,交流而已,为了相互促进
发表于 2010-5-24 11:38:42 | 显示全部楼层
嗯,这个很好,我那天就做了一个类似的,就是对中文二次加密,不过后来用了url rewrite以后,就得三次加密了...

本版积分规则