This article describes how to add a service layer in the controller and model to take charge of the business logic. encapsulated calling interfaces can be reused by the controller, improving the reusability of common business logic, the Model interface is called when the specific business implementation is designed. As you know, CodeIgniter is a framework of MVC layering. Generally, you write the business logic to the Controller, while the Model is only responsible for dealing with databases.
However, as the business becomes more complex and the controller becomes more and more bloated, for example, if a user places an order, there will inevitably be a series of operations: updating the shopping cart, adding order records, adding members to points, etc, the order may be placed in multiple scenarios. if such code is put in the controller, it is very bloated and difficult to reuse. if you put the model, the persistent layer and the business layer will be coupled. The company's project is that many people write some business logic into the model, and other models are called in the model, that is, the business layer and the persistent layer are coupled with each other. This is extremely unreasonable, making the model difficult to maintain and the methods difficult to reuse.
Is it possible to consider adding a service layer in the controller and model to take charge of the business logic, and the encapsulated calling interface can be reused by the controller.
In this way, the tasks at each layer are clear:
Model (DAO): The data persistence layer is used to encapsulate database operations.
Service: The business logic layer is responsible for the logic application design of the business module. the controller can call the service interface to implement business logic processing, improving the reusability of common business logic, the Model interface is called when the specific business implementation is designed.
Controller: control layer, responsible for specific business process control. here, the service layer is called to return data to the view.
View: displays front-end pages and is closely related to the Controller.
Based on the preceding description, the implementation process is as follows:
(1) enable CI to load the service, and put the service directory under the application. because the CI system does not have a service, create a new extension MY_Service.php under application/core.
The code is as follows:
<? Php
Class MY_Service
{
Public function _ construct ()
{
Log_message ('debug', "Service Class Initialized ");
}
Function _ get ($ key)
{
$ CI = & get_instance ();
Return $ CI-> $ key;
}
}
(2) expand the CI_Loader implementation, load the service, and create the MY_Loader.php file under application/core:
The code is as follows:
<? 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) Simple example:
Call service in the controller:
The code is as follows:
<? 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 calls model:
The code is as follows:
<? 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;
}
}
In the model, you only deal with db:
The code is as follows:
<? 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 ');
}
}
This is the basic idea.