您的位置 首页 php

CI框架引入service层

一、前戏:

C I框架是典型的MVC模式,随着业务的不断更新迭代,慢慢发现C层变得越来越臃肿,身高和体重一个数值。更痛的是,同一个业务逻辑,不能复用,需要复制一份,进而影响了后期可维护,修过一个逻辑,就要想着所有的地方,恐怕遗漏。

扯皮:

 这个bug确实是我写的,但是抛开这点不谈,你们就没有一点责任吗?review的时候大家也都在场,你们当时是不是没有认真对待,还有,测试是怎么做的测试?难道这些都是摆设吗,是走过场吗?幸好这次线上事故没有造成资损,但是希望大家引以为戒,这周的周报我要看到大家的反思和进步!  

二、Service 解决了什么?

1、高内聚、低耦合。实现解耦,分层设计,在Controller 与 model 新增 service 层,使代码结构更清晰,C层更灵活;

2、提高复用性,抽象封装业务逻辑,后期易维护拓展;

3、承上启下,对Controller 层提供业务逻辑封装,聚合多个model层的数据组装。

三、如何引入Service?

1、需要引入加载service的相关文件?

答:如何加载service文件,需要拓展CI_Loader。

上代码: BASE_Loader.php,

注意:以下的 BASE_ 是文件前缀,在配置文件中可自定义,

 $config['subclass_prefix'] = 'BASE_';(代码所在地:application/config/config.php)
  

新建文件路由:application/core/BASE_Loader.php

 <?php
defined('BASEPATH') or exit('No direct script access allowed');

class BASE_Loader extends CI_Loader
{
    /**
     * List of loaded services
     *
     * @var array
     * @access protected
     */    protected $_ci_services = array();
    /**
     * List of paths to load services from
     *
     * @var array
     * @access protected
     */    protected $_ci_service_paths = array();


    /**
     * 
     * 定义service文件夹名称  (注意点一)
     *
     */   
    protected $_ci_service_dir_name = 'services';

    /**
     * Constructor
     *
     * Set the path to the Service files
     */    public function __construct()
    {

        parent::__construct();
        load_class('Service', 'core');
        $this->_ci_service_paths = array(APPPATH);
    }

    /**
     * Service Loader
     *
     *
     * @param string    the name of the class
     * @param mixed    the optional parameters
     * @param string    an optional object name
     * @return    boolean
     */    public function service($service = '', $params = null, $object_name = null)
    {
        if (is_array($service)) {
            foreach ($service as $class) {
                $this->service($class, $params);
            }

            return true;
        }

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

        if (!is_null($params) && !is_array($params)) {
            $params = null;
        }

        $subDir = '';

       
        if (($last_slash = strrpos($service, '/')) !== false) {
            
            $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 . $this->_ci_service_dir_name . '/' . $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 true;
        }


        return true;
    }
}  

2、如何获取service操作句柄

新建文件:application/core/BASE_Service.php

和上边的文件同文件夹同级。

 <?php
defined('BASEPATH') OR exit('No direct script access allowed');

class BASE_Service
{
    protected $_nowTime;

    public function __construct()
    {
       // log_message('debug', "Service Class Initialized");
        $this->_nowTime = time();
    }
    function __get($key)
    {
        $CI = & get_instance();
        return $CI->$key;
    }


    /**
     * 返回参数
     * @param string $msg
     * @param int $code
     * @param array $data
     * @return array
     */    protected function response($msg = '', $code = RESPONSE_CODE_SUCC, $data = [])
    {
        return [
            'code' => $code,
            'msg'  => $msg,
            'data' => $data
        ];
    }
}
  

3、新建文件夹

文件夹名称为BASE_Loader.php 定义的$_ci_service_dir_name = ‘services’;

在application文件夹下新建文件夹services。

4、应用:

4.1 新建Test_service.php

文件所在位置:application/services/common/Test_service.php ,(我这里按照业务又分了文件夹,所以多了一个common)

 <?php

class Test_service extends BASE_Service
{
    public function __construct()
    {
        parent::__construct();

    }


    public function getUserInfo($id)
    {
        return "This is test,ID:".$id;
    }
}  

4.2 Controller 调用

         $this->load->service('common/Test_service');
        $result = $this->test_service->getUserInfo(1);  

注意:$this->test_service->getUserInfo(1); 中的test_service 为小写,因为在注册加载service文件的时候,全部转义为小写了。该逻辑在代码:application/core/BASE_Loader.php:87

(end)

以上就实现了C I框架引入service。

注意点:

1、配置文件中设置的扩展类前缀:subclass_prefix

2、新建的文件夹名称是否和自己在BASE_Loader.php中配置的一致,默认是:$_ci_service_dir_name = ‘services’;

3、调用的时候,确认是否小写服务名称。

我为人人,人人为我,美美与共,天下大同。

文章来源:智云一二三科技

文章标题:CI框架引入service层

文章地址:https://www.zhihuclub.com/153224.shtml

关于作者: 智云科技

热门文章

网站地图