如何让CI框架支持service层


Posted in PHP onOctober 29, 2014

大家知道CodeIgniter框架式MVC分层的,通常大家把业务逻辑写到Controller中,而Model只负责和数据库打交道。

但是随着业务越来越复杂,controller越来越臃肿,举一个简单的例子,比如说用户下订单,这必然会有一系列的操作:更新购物车、添加订单记录、会员添加积分等等,且下订单的过程可能在多种场景出现,如果这样的代码放controller中则很臃肿难以复用,如果放model会让持久层和业务层耦合。现在公司的项目就是,很多人将一些业务逻辑写到model中去了,model中又调其它model,也就是业务层和持久层相互耦合。这是极其不合理的,会让model难以维护,且方法难以复用。

是不是可以考虑在controller和model中加一个业务层service,由它来负责业务逻辑,封装好的调用接口可以被controller复用。

这样各层的任务就明确了:
Model(DAO):数据持久层的工作,对数据库的操作都封装在这。
Service : 业务逻辑层,负责业务模块的逻辑应用设计,controller中就可以调用service的接口实现业务逻辑处理,提高了通用的业务逻辑的复用性,设计到具体业务实现会调用Model的接口。
Controller :控制层,负责具体业务流程控制,这里调用service层,将数据返回到视图
View : 负责前端页面展示,与Controller紧密联系。

基于上面描述,实现过程:
(1)让CI能够加载service,service目录放在application下,因为CI系统没有service,则在application/core下新建扩展MY_Service.php

<?php

class MY_Service

{

    public function __construct()

    {

        log_message('debug', "Service Class Initialized");

    }

    function __get($key)

    {

        $CI = & get_instance();

        return $CI->$key;

    }

}

(2)扩展CI_Loader实现,加载service,在application/core下新建MY_Loader.php文件:

<?php

class MY_Loader extends CI_Loader

{

    /**

  * List of loaded sercices

  *

  * @var array

  * @access protected

  */

 protected $_ci_services = array();

 /**

  * List of paths to load sercices from

  *

  * @var array

  * @access protected

  */

 protected $_ci_service_paths  = array();

    /**

     * Constructor

     * 

     * Set the path to the Service files

     */

    public function __construct()

    {

        parent::__construct();

        $this->_ci_service_paths = array(APPPATH);

    }

    /**

     * Service Loader

     * 

     * This function lets users load and instantiate classes.

  * It is designed to be called from a user's app controllers.

  *

  * @param string the name of the class

  * @param mixed the optional parameters

  * @param string an optional object name

  * @return void

     */

    public function service($service = '', $params = NULL, $object_name = NULL)

    {

        if(is_array($service))

        {

            foreach($service as $class)

            {

                $this->service($class, $params);

            }

            return;

        }

        if($service == '' or isset($this->_ci_services[$service])) {

            return FALSE;

        }

        if(! is_null($params) && ! is_array($params)) {

            $params = NULL;

        }

        $subdir = '';

        // Is the service in a sub-folder? If so, parse out the filename and path.

        if (($last_slash = strrpos($service, '/')) !== FALSE)

        {

                // The path is in front of the last slash

                $subdir = substr($service, 0, $last_slash + 1);

                // And the service name behind it

                $service = substr($service, $last_slash + 1);

        }

        foreach($this->_ci_service_paths as $path)

        {

            $filepath = $path .'service/'.$subdir.$service.'.php';

            if ( ! file_exists($filepath))

            {

                continue;

            }

            include_once($filepath);

            $service = strtolower($service);

            if (empty($object_name))

            {

                $object_name = $service;

            }

            $service = ucfirst($service);

            $CI = &get_instance();

            if($params !== NULL)

            {

                $CI->$object_name = new $service($params);

            }

            else

            {

                $CI->$object_name = new $service();

            }

            $this->_ci_services[] = $object_name;

            return;

        }

    }

}

(3)简单例子实现:
控制器中调用service :

<?php

class User extends CI_Controller

{

    public function __construct() 

    {

  

        parent::__construct();

        $this->load->service('user_service');

    }

    public function login()

    {

        $name = 'phpddt.com';

        $psw = 'password';

        print_r($this->user_service->login($name, $psw));

    }

}

service中调用model :

<?php

class User_service extends MY_Service

{

    public function __construct()

    {

        parent::__construct();

        $this->load->model('user_model');

    }

    public function login($name, $password)

    {

        $user = $this->user_model->get_user_by_where($name, $password);

        //.....

        //.....

        //.....

        return $user;

    }

}

model中你只跟db打交道:

<?php

class User_model extends CI_Model

{

    public function __construct()

    {

        parent::__construct();

    }

    public function get_user_by_where($name, $password)

    {

        //$this->db

        //......

        //......

        return array('id' => 1, 'name' => 'mckee');

    }

}

基本实现思路就是这样的。

PHP 相关文章推荐
PHP之变量、常量学习笔记
Mar 27 PHP
php下网站防IP攻击代码,超级实用
Oct 24 PHP
关于ob_get_contents(),ob_end_clean(),ob_start(),的具体用法详解
Jun 24 PHP
php json_encode值中大括号与花括号区别
Sep 30 PHP
discuz加密解密函数使用方法和中文注释
Jan 21 PHP
destoon首页调用求购供应信息的地区名称的方法
Aug 21 PHP
百度实时推送api接口应用示例
Oct 21 PHP
php判断并删除空目录及空子目录的方法
Feb 11 PHP
PHP实现HTML页面静态化的方法
Nov 04 PHP
PHP简单的MVC框架实现方法
Dec 01 PHP
简单的自定义php模板引擎
Aug 26 PHP
php图形jpgraph操作实例分析
Feb 22 PHP
使用array_map简单搞定PHP删除文件、删除目录
Oct 29 #PHP
PHPUnit安装及使用示例
Oct 29 #PHP
laravel安装和配置教程
Oct 29 #PHP
laravel 4安装及入门图文教程
Oct 29 #PHP
thinkphp浏览历史功能实现方法
Oct 29 #PHP
thinkphp获取栏目和文章当前位置的方法
Oct 29 #PHP
thinkphp实现like模糊查询实例
Oct 29 #PHP
You might like
优化php效率,提高php性能的一些方法
2011/03/24 PHP
将时间以距今多久的形式表示,PHP,js双版本
2012/09/25 PHP
深入浅出php socket编程
2015/05/13 PHP
php实现向javascript传递数组的方法
2015/07/27 PHP
php图片合成方法(多张图片合成一张)
2017/11/25 PHP
node.js中的http.createClient方法使用说明
2014/12/15 Javascript
JavaScript中的getTime()方法使用详解
2015/06/10 Javascript
js判断日期时间有效性的方法
2015/10/24 Javascript
HTML5canvas 绘制一个圆环形的进度表示实例
2016/12/16 Javascript
微信小程序 安全包括(框架、功能模块、账户使用)详解
2017/01/16 Javascript
微信公众号菜单配置微信小程序实例详解
2017/03/31 Javascript
BootStrap Table实现server分页序号连续显示功能(当前页从上一页的结束序号开始)
2017/09/12 Javascript
Vue双向绑定实现原理与方法详解
2020/05/07 Javascript
基于原生js实现判断元素是否有指定class名
2020/07/11 Javascript
js实现列表按字母排序
2020/08/11 Javascript
python中的hashlib和base64加密模块使用实例
2014/09/02 Python
Python入门篇之字符串
2014/10/17 Python
用Python编写简单的定时器的方法
2015/05/02 Python
Django1.7+python 2.78+pycharm配置mysql数据库
2016/10/09 Python
Python数据结构与算法之图结构(Graph)实例分析
2017/09/05 Python
Python requests库用法实例详解
2018/08/14 Python
面向初学者的Python编辑器Mu
2018/10/08 Python
Python button选取本地图片并显示的实例
2019/06/13 Python
python替换字符串中的子串图文步骤
2019/06/19 Python
如何更优雅地写python代码
2019/07/02 Python
Python装饰器实现方法及应用场景详解
2020/03/26 Python
Python并发爬虫常用实现方法解析
2020/11/19 Python
为奢侈时尚带来了慈善元素:Olivela
2018/09/29 全球购物
奥地利购买珠宝和手表网站:ELLA JUWELEN
2019/09/03 全球购物
机械工程系毕业生求职信
2013/09/27 职场文书
2015年幼儿园毕业感言
2014/02/12 职场文书
暑期教师培训方案
2014/06/07 职场文书
2015年社区工会工作总结
2015/05/26 职场文书
开场白怎么写
2015/06/01 职场文书
生日祝酒词大全
2015/08/10 职场文书
2016抗战胜利71周年红领巾广播稿
2015/12/18 职场文书