In this paper, we introduce a service layer service in controller and model, which is responsible for the business logic, the packaged calling interface can be reused by controller, and the reuse of general business logic is improved, and the design to the concrete business implementation will call model's interface.
As you know, CodeIgniter framework MVC is layered, and often everyone writes business logic to the controller, and model is only responsible for dealing with the database.
But as the business becomes more complex and the controller becomes bloated, a simple example, such as a user placing an order, will inevitably be a series of actions: updating the shopping cart, adding the order history, adding points to the member, and so on, and the process of placing the order may appear in a variety of scenarios, If such a code in the controller is very bloated and difficult to reuse, if the model will let the persistence layer and the business layer coupling. Now the company's project is that a lot of people write some business logic into the model, and the model in the other model, that is, the business layer and the persistence layer coupling each other. This is extremely unreasonable, makes the model difficult to maintain, and the method is difficult to reuse.
Is it possible to consider adding a business layer service to the controller and model, which is responsible for the business logic, and the encapsulated calling interface can be reused by the controller.
The tasks on each level are clear:
Model (DAO): The work of the data persistence layer, which is encapsulated in the operation of the database.
Service: The business Logic layer, is responsible for the business module logic application design, the controller can invoke the service interface to realize the business logic processing, improves the common business logic reusability, designs to the concrete business implementation to call model's interface.
Controller: Control layer, responsible for specific business process control, call service layer here, return data to view
View: Responsible for front-end page display, close contact with controller.
Based on the above description, the implementation process:
(1) Let CI be able to load the Service,service directory under Application, because the CI system does not have a Service, then create a new extension under Application/core my_service.php
Copy CodeThe 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) Extend the Ci_loader implementation, load the service, create a new my_loader.php file under Application/core:
Copy CodeThe 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 being 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 implementation:
Call Service in Controller:
Copy CodeThe 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));
}
}
Call model in service:
Copy CodeThe 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 model you only deal with DB:
Copy CodeThe 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 ');
}
}
The basic idea of implementation is this.
How to enable the CI framework to support the service layer