如何让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 相关文章推荐
smarty section简介与用法分析
Oct 03 PHP
基于PHP CURL用法的深入分析
Jun 09 PHP
win7计划任务定时执行PHP脚本设置图解
May 09 PHP
通过php修改xml文档内容的方法
Jan 23 PHP
php基于Fleaphp框架实现cvs数据导入MySQL的方法
Feb 23 PHP
Laravel+jQuery实现AJAX分页效果
Sep 14 PHP
详解php中的implements 使用
Jun 13 PHP
thinkphp3.2实现在线留言提交验证码功能
Jul 19 PHP
支持汉转拼和拼音分词的PHP中文工具类ChineseUtil
Feb 23 PHP
phpstudy2018升级MySQL5.5为5.7教程(图文)
Oct 24 PHP
php 调用百度sms来发送短信的实现示例
Nov 02 PHP
如何在PHP中生成随机数
Jun 04 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 ? EasyUI DataGrid 资料取的方式介绍
2012/11/07 PHP
PHP保存Base64图片base64_decode的问题整理
2019/11/04 PHP
Thinkphp 框架配置操作之配置加载与读取配置实例分析
2020/05/15 PHP
javascript同步Import,同步调用外部js的方法
2008/07/08 Javascript
Javascript 继承实现例子
2009/08/12 Javascript
JavaScript中实现块作用域的方法
2010/04/01 Javascript
JS 面向对象之神奇的prototype
2011/02/26 Javascript
jquery创建并行对象或者合并对象的实现代码
2012/10/10 Javascript
JavaScript表达式:URL 协议介绍
2013/03/10 Javascript
js取消单选按钮选中并判断对象是否为空
2013/11/14 Javascript
jQuery中:animated选择器用法实例
2014/12/29 Javascript
JavaScript通过事件代理高亮显示表格行的方法
2015/05/27 Javascript
js文字横向滚动特效
2015/11/11 Javascript
JS异步文件分片断点上传的实现思路
2016/12/25 Javascript
JS动态遍历json中所有键值对的方法(不知道属性名的情况)
2016/12/28 Javascript
Javascript实现页面滚动时导航智能定位
2017/05/06 Javascript
VueCli3构建TS项目的方法步骤
2018/11/07 Javascript
微信小程序实现搜索指定景点周边美食、酒店
2019/05/18 Javascript
vue cli安装使用less的教程详解
2019/07/12 Javascript
js时间转换毫秒的实例代码
2019/08/21 Javascript
layui点击弹框页面 表单请求的方法
2019/09/21 Javascript
使用vue重构资讯页面的实例代码解析
2019/11/26 Javascript
React 条件渲染最佳实践小结(7种)
2020/09/27 Javascript
python中numpy.zeros(np.zeros)的使用方法
2017/11/07 Python
python使用turtle库绘制树
2018/06/25 Python
Python实现的从右到左字符串替换方法示例
2018/07/06 Python
django 使用全局搜索功能的实例详解
2019/07/18 Python
Python阶乘求和的代码详解
2020/02/14 Python
jupyter notebook 多环境conda kernel配置方式
2020/04/10 Python
奢华时尚的独特视角:La Garçonne
2018/06/07 全球购物
阿玛尼意大利官网:Armani意大利
2018/10/30 全球购物
微型企业创业投资计划书
2014/01/10 职场文书
工作总结与自我评价
2014/09/18 职场文书
交警正风肃纪剖析材料
2014/10/29 职场文书
2015年敬老院工作总结
2015/05/18 职场文书
实习证明模板
2015/06/16 职场文书