首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

如何讓 CodeIgniter 框架支援 Service 層架構

     編輯:PHP 綜合知識

痛點背景

CodeIgniter 採 MVC 分層,業務邏輯通常寫在 Controller,Model 僅負責資料庫操作。隨業務複雜度提升,Controller 膨脹難維護。以「用戶下單」為例:更新購物車、新增訂單、會員加分等一連串操作,且下單場景多樣,若寫在 Controller 難以復用;寫在 Model 又會導致持久層與業務層耦合。現有專案常見將業務邏輯寫在 Model 並互相調用,極不合理,導致 Model 難維護、方法難復用。

解決方案:引入 Service 層

在 Controller 與 Model 間加入業務邏輯層 Service,封裝業務邏輯,提供介面供 Controller 復用。

各層職責劃分

  • Model (DAO):資料持久層,封裝所有資料庫操作
  • Service:業務邏輯層,負責業務模組邏輯設計,Controller 調用 Service 介面實現業務處理,提高復用性,具體實現調用 Model 介面
  • Controller:控制層,負責業務流程控制,調用 Service 並將資料回傳視圖
  • View:前端展示層,與 Controller 緊密聯繫

實作步驟

(1)建立 MY_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
{
    protected $_ci_services = array();
    protected $_ci_service_paths = array();

    public function __construct()
    {
        parent::__construct();
        $this->_ci_service_paths = array(APPPATH);
    }

    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 = '';
        if (($last_slash = strrpos($service, '/')) !== FALSE) {
            $subdir = substr($service, 0, $last_slash + 1);
            $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)實際應用範例

Controller 調用 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 僅處理資料庫:

<?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');
    }
}

基本實作思路即如此。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved