如何让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 截取字符串 分别适合GB2312和UTF8编码情况
Feb 12 PHP
Ajax+PHP边学边练 之五 图片处理
Dec 03 PHP
ajax+php打造进度条代码[readyState各状态说明]
Apr 12 PHP
php生成随机密码的几种方法
Jan 17 PHP
PHP下通过exec获得计算机的唯一标识[CPU,网卡 MAC地址]
Jun 09 PHP
PHP 数据结构 算法描述 冒泡排序 bubble sort
Jul 10 PHP
PHP高级对象构建 工厂模式的使用
Feb 05 PHP
PHP jQuery表单,带验证具体实现方法
Feb 15 PHP
VB中的RasEnumConnections函数返回632错误解决方法
Jul 29 PHP
PHP图片加水印实现方法
May 06 PHP
Laravel5.7 数据库操作迁移的实现方法
Apr 12 PHP
php使用goto实现自动重启swoole、reactphp、workerman服务的代码
Apr 13 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启发和小结
2010/11/01 PHP
Yii2基于Ajax自动获取表单数据的方法
2016/08/10 PHP
Thinkphp 中 distinct 的用法解析
2016/12/14 PHP
ExtJS 学习专题(一) 如何应用ExtJS(附实例)
2010/03/11 Javascript
JavaScrip单线程引擎工作原理分析
2010/09/04 Javascript
jquery动画1.加载指示器
2012/08/24 Javascript
js页面跳转的常用方法整理
2013/10/18 Javascript
JavaScript中instanceof运算符的用法总结
2013/11/19 Javascript
修改或扩展jQuery原生方法的代码实例
2015/01/13 Javascript
如何减少浏览器的reflow和repaint
2015/02/26 Javascript
js实时获取窗口大小变化的实例代码
2016/11/18 Javascript
JS使用cookie实现只出现一次的广告代码效果
2017/04/22 Javascript
angularjs定时任务的设置与清除示例
2017/06/02 Javascript
javascript实现获取一个日期段内每天不同的价格(计算入住总价格)
2018/02/05 Javascript
基于angular6.0实现的一个组件懒加载功能示例
2018/04/12 Javascript
Vue基础学习之项目整合及优化
2019/06/02 Javascript
nodejs的安装使用与npm的介绍
2019/09/11 NodeJs
公众号SVG动画交互实战代码
2020/05/31 Javascript
js实现弹幕飞机效果
2020/08/27 Javascript
python中base64加密解密方法实例分析
2015/05/16 Python
Django获取应用下的所有models的例子
2019/08/30 Python
Python模拟登录之滑块验证码的破解(实例代码)
2019/11/18 Python
Python selenium环境搭建实现过程解析
2020/09/08 Python
python实现简单的学生管理系统
2021/02/22 Python
CSS3.0实现霓虹灯按钮动画特效的示例代码
2021/01/12 HTML / CSS
五好党支部事迹材料
2014/02/06 职场文书
护理中职生求职信范文
2014/02/24 职场文书
新农村建设标语
2014/06/24 职场文书
教师纪念9.18事件演讲稿范文
2014/09/14 职场文书
销售辞职信范文
2015/03/02 职场文书
婚礼答谢词范文
2015/09/29 职场文书
小学大队长竞选稿
2015/11/20 职场文书
创业计划书之酒店
2019/08/30 职场文书
CSS3 天气图标动画效果
2021/04/06 HTML / CSS
游戏《铁拳》动画化!2022年年内播出
2022/03/21 日漫
修改Nginx配置返回指定content-type的方法
2022/09/23 Servers