了解知识
大家知道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
 
  1. <?php 
  2.   
  3. class MY_Service 
  4.     public function __construct() 
  5.     { 
  6.         log_message('debug'"Service Class Initialized"); 
  7.          
  8.     } 
  9.   
  10.     function __get($key
  11.     { 
  12.         $CI = & get_instance(); 
  13.         return $CI->$key
  14.     } 
  15.   
 
(2)扩展CI_Loader实现,加载service,在application/core下新建MY_Loader.php文件:
 
  1. <?php 
  2.   
  3. class MY_Loader extends CI_Loader 
  4.     /** 
  5.      * List of loaded sercices 
  6.      * 
  7.      * @var array 
  8.      * @access protected 
  9.      */ 
  10.     protected $_ci_services = array(); 
  11.     /** 
  12.      * List of paths to load sercices from 
  13.      * 
  14.      * @var array 
  15.      * @access protected 
  16.      */ 
  17.     protected $_ci_service_paths        = array(); 
  18.      
  19.     /** 
  20.      * Constructor 
  21.      *  
  22.      * Set the path to the Service files 
  23.      */ 
  24.     public function __construct() 
  25.     { 
  26.          
  27.         parent::__construct(); 
  28.          
  29.         $this->_ci_service_paths = array(APPPATH); 
  30.     } 
  31.      
  32.     /** 
  33.      * Service Loader 
  34.      *  
  35.      * This function lets users load and instantiate classes. 
  36.      * It is designed to be called from a user's app controllers. 
  37.      * 
  38.      * @param   string  the name of the class 
  39.      * @param   mixed   the optional parameters 
  40.      * @param   string  an optional object name 
  41.      * @return  void 
  42.      */ 
  43.     public function service($service = ''$params = NULL, $object_name = NULL) 
  44.     { 
  45.         if(is_array($service)) 
  46.         { 
  47.             foreach($service as $class
  48.             { 
  49.                 $this->service($class$params); 
  50.             } 
  51.              
  52.             return
  53.         } 
  54.          
  55.         if($service == '' or isset($this->_ci_services[$service])) { 
  56.             return FALSE; 
  57.         } 
  58.   
  59.         if(! is_null($params) && ! is_array($params)) { 
  60.             $params = NULL; 
  61.         } 
  62.          
  63.         $subdir = ''
  64.   
  65.         // Is the service in a sub-folder? If so, parse out the filename and path. 
  66.         if (($last_slash = strrpos($service'/')) !== FALSE) 
  67.         { 
  68.                 // The path is in front of the last slash 
  69.                 $subdir = substr($service, 0, $last_slash + 1); 
  70.   
  71.                 // And the service name behind it 
  72.                 $service = substr($service$last_slash + 1); 
  73.         } 
  74.          
  75.         foreach($this->_ci_service_paths as $path
  76.         { 
  77.              
  78.             $filepath = $path .'service/'.$subdir.$service.'.php'
  79.              
  80.             if ( ! file_exists($filepath)) 
  81.             { 
  82.                 continue
  83.             } 
  84.              
  85.             include_once($filepath); 
  86.              
  87.             $service = strtolower($service); 
  88.   
  89.             if (emptyempty($object_name)) 
  90.             { 
  91.                 $object_name = $service
  92.             } 
  93.              
  94.             $service = ucfirst($service); 
  95.             $CI = &get_instance(); 
  96.             if($params !== NULL) 
  97.             { 
  98.                 $CI->$object_name = new $service($params); 
  99.             } 
  100.             else 
  101.             { 
  102.                 $CI->$object_name = new $service(); 
  103.             } 
  104.              
  105.             $this->_ci_services[] = $object_name
  106.              
  107.             return
  108.         } 
  109.     } 
  110.      
 
(3)简单例子实现:
控制器中调用service :
 
  1. <?php 
  2.   
  3. class User extends CI_Controller 
  4.     public function __construct()  
  5.     { 
  6.          
  7.         parent::__construct(); 
  8.         $this->load->service('user_service'); 
  9.     } 
  10.      
  11.     public function login() 
  12.     { 
  13.         $name = 'phpddt.com'
  14.         $psw = 'password'
  15.         print_r($this->user_service->login($name$psw)); 
  16.     } 
  17.      
 
service中调用model :
 
  1. <?php 
  2.   
  3. class User_service extends MY_Service 
  4.     public function __construct() 
  5.     { 
  6.         parent::__construct(); 
  7.         $this->load->model('user_model'); 
  8.     } 
  9.      
  10.     public function login($name$password
  11.     { 
  12.         $user = $this->user_model->get_user_by_where($name$password); 
  13.          
  14.         //..... 
  15.         //..... 
  16.         //..... 
  17.          
  18.         return $user
  19.     } 
  20.      
model中你只跟db打交道:
 
  1. <?php 
  2.   
  3. class User_model extends CI_Model 
  4.     public function __construct() 
  5.     { 
  6.         parent::__construct(); 
  7.     } 
  8.      
  9.     public function get_user_by_where($name$password
  10.     { 
  11.          
  12.         //$this->db 
  13.         //...... 
  14.         //...... 
  15.         return array('id' => 1, 'name' => 'mckee'); 
  16.     } 
 
基本实现思路就是这样的。
标签: PHP CI框架
扩展知识