• CI 扩展 Service


    CI 扩展 Service

    说明

    CodeIgniter是一套典型的MVC框架,M负责数据,C负责交互,V负责视图,但是随着业务逻辑越来越复杂,
    必然会涉及到一些列操作过程,例如用户下订单,就会存在校验,核算金额,保存记录,增加积分等系列操作,
    显然无法将所有逻辑都写在Controller中,导致代码臃肿以致无法维护。
    为了解决以上问题,可以增加一个业务层service,由service负责业务逻辑的编写,分装好接口供Controller调用。

    • Model:模型层,作为数据载体
    • Service : 业务逻辑层,负责业务模块的逻辑应用设计
    • Controller :控制层,负责具体业务流程控制,调用service层,将数据返回到视图
    • View : 视图层,负责展示视图及数据

    CodeIgniter中application是应用程序目录,其中Models,Views,Controllers分别对应M、V、C目录,
    同样的,希望在application目录下存在services目录,用来存放业务逻辑层代码。

    实现

    父类

    首先,我们在application/core下新建扩展MY_Service.php,作为所有service类的父类,代码如下

    <?php
    
    class MY_Service
    {
        public function __construct()
        {
            log_message('info', "Service Class Initialized");
        }
     
        function __get($key)
        {
            $CI = & get_instance();
            return $CI->$key;
        }
    }
    

    加载

    其次,我们在application/core下新建扩展MY_Loader.php,扩展默认的Loader类,在其中添加加载service的方法,
    这样就可以通过loader加载对应service类

    <?php
    if (! defined ( 'BASEPATH' )) exit ( 'No direct access allowed.' );
    
    class MY_Loader extends CI_Loader {
        
        //service path
        protected $_ci_services_paths = array(APPPATH);
        
        //service class
        protected $_ci_services = array();
        
        
        
        public function __construct() {
            parent::__construct ();
        }
        
        /**
        * 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	object
        */
        public function service($service = '', $params = NULL, $object_name = NULL)
        {
            if (empty($service))
            {
                return $this;
            }
            else if(is_array($service))
            {
                //Is the service is an array?If so,load every key
                foreach ($service as $key => $value)
                {
                    is_int($key) ? $this->service($value, '', $object_name) : $this->service($key, $value, $object_name);
                }
                
                return $this;
            }
            
            $path = '';
            
            // 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
                $path = substr($service, 0, ++$last_slash);
                
                // And the service name behind it
                $service = substr($service, $last_slash);
            }
            
            if (empty($object_name))
            {
                $object_name = $service;
            }
    
            $object_name = strtolower($object_name);
            if (in_array($object_name, $this->_ci_services, TRUE))
            {
                return $this;
            }
            
            $CI =& get_instance();
            if (isset($CI->$object_name))
            {
                throw new RuntimeException('The service name you are loading is the name of a resource that is already being used: '.$object_name);
            }
            
            //load MY_Service
            $class = config_item('subclass_prefix').'Service';
            $app_path = APPPATH.'core'.DIRECTORY_SEPARATOR;
            
            if(!class_exists($class, FALSE))
            {
                if (file_exists($app_path.$class.'.php'))
                {
                    require_once($app_path.$class.'.php');
                    if (!class_exists($class, FALSE))
                    {
                        throw new RuntimeException($app_path.$class.".php exists, but doesn't declare class ".$class);
                    }
                }
            }
            
            $service = ucfirst($service);
            if (!class_exists($service, FALSE))
            {   
                //load service files
                foreach ($this->_ci_services_paths as $service_path)
                {
                    if ( ! file_exists($service_path.'services/'.$path.$service.'.php'))
                    {
                        continue;
                    }
                    //default path application/services/
                    include_once($service_path.'services/'.$path.$service.'.php');
                    
                    $CI = &get_instance();
                    
                    if($params !== NULL)
                    {
                        $CI->$object_name = new $service($params);
                    }
                    else
                    {
                        $CI->$object_name = new $service();
                    }
                    
                    $this->_ci_services[] = $object_name;
                    
                    if (!class_exists($service, FALSE))
                    {
                        throw new RuntimeException($service_path."services/".$path.$service.".php exists, but doesn't declare class ".$service);
                    }
                    
                    break;
                }
            
            }
        
            return $this;
        }
    }
    

    调用

    在application/services目录下创建一个示例文件Demo.php,代码如下

    <?php
    class Demo extends MY_Service{
        
        public function Hello()
        {
            return "Hello World";
        }
    }
    

    在Controller中调用Demo服务,代码如下

    <?php
    
    defined('BASEPATH') OR exit('No direct script access allowed');
    
    class Home extends MY_Controller {
        
        public function Index()
        {
            //调用对应的服务
            $this->load->service('Demo');
            
            //执行服务方法
            echo $this->index->Hello();
        }
    }
    

    在浏览器中查看可以看到对应的输出为Hello World

  • 相关阅读:
    Java学习8.17
    Java学习8.16
    Java学习8.15
    Java学习8.14
    Java学习8.13
    Java学习8.12
    Java学习8.11
    131. Palindrome Partitioning 回文串分割
    40. Combination Sum II 不允许使用重复元素
    39. Combination Sum 凑出一个和,可以重复用元素(含duplicates)
  • 原文地址:https://www.cnblogs.com/SLchuck/p/5804555.html
Copyright © 2020-2023  润新知