For basic web development, we have become accustomed to the MVC architecture. The model layer (M) provides persistent data objects with data access, the control layer (C) completes the business logic processing, and the view Layer (V) provides template representation. Where the control layer interacts with the model layer and the view layer to form the entire system.
This hierarchical approach is logically decoupled, and many languages such as Java and Python frameworks have their own implementations, such as struts, which are implemented in a bean+jsp+hibernate manner. Django implements the middleware approach. Whether the implementation of the Java framework or the implementation of the Python framework, it is better to solve the problem of interaction between MVC, so that each level becomes a separate component, each layer of the component can be reused elsewhere. Java beans can also be packaged as SOAP services, in addition to being available for JSP use. This ensures both the logical separation between the layers and the physical separation between the layers. such as Java beans can be deployed on a distributed application server alone. EJB is a good example. For some PHP frameworks that are widely used, there is a lack of physical independence considerations in implementation.
In the case of YII framework, the organizational structure of YII framework is as follows:
Site
|____resources
|____protected
|____config
|____controllers
|____models
|____views
|____components
|____framework
|____index.php
Resources represent some of the resource information, slices, style sheets, etc. of the site. Freamework is the framework core document. index.php is a portal file, and all access paths are standard with index.php followed parameters. and protected is the business logic needs of the MVC layer three and the system needs some configuration information. The componets in protected is the component class of the system, if there is a function library that is not related to the system orchestration, but is required in the business logic, it can be placed in this directory as a component, and if the component is registered within the configuration file, it will produce an instance of them for invocation when the system is running. The process of execution is as follows:
650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M01/48/F0/wKiom1QMYV7S5rcpAAEH_88CYno485.jpg "title=" Basic flowchart. png "alt=" wkiom1qmyv7s5rcpaaeh_88cyno485.jpg "/>
650) this.width=650; "src="/e/u261/themes/default/images/spacer.gif "style=" Background:url ("/e/u261/lang/zh-cn/ Images/localimage.png ") no-repeat center;border:1px solid #ddd;" alt= "Spacer.gif"/>
As you can see, the action needs to interact with the model layer and the view layer at the same time, within the action, there is not only the business logic, but also the method of the model layer and the method of the view layer. In this way, the business logic and the model layer, the view layer there is a tight coupling relationship. This hierarchy applies to basic Web sites or meets requirements, but is not extensible or modifiable. If you now want to wrap the business logic as a rest-style or soap service, you can only re-write the action that contains the business logic, because the action now contains the output method of the page, not the result of the data alone. The need to use the same dynamic data to demonstrate different representations can only be achieved by judging (modifying) the way it is and not by adding classes or simple actions (extensions). This violates the object-oriented open closure principle. Because system requirements are often changed frequently, if we often modify existing code, not only will cause the existing system code structure confusion, and very easy to create hidden, difficult to find errors. Therefore, only through the expansion to achieve the requirements of the change, the system is the most secure. Our work will be more relaxed and efficient.
Since the source code provided by Yii is not a perfect solution to the problem of extensibility and modification, then why don't we make a small transformation of it so that it can be qualified for higher requirements? As the saying goes, in the software world, adding a layer can solve all the problems. Therefore, we also decided to use the "add a layer" approach to improve the scalability of our system and modifiable. Because Yii uses URI routing to find the action and act on it, the response result is also generated by the action method. Therefore, in order not to destroy the YII framework, we can only add a layer below the action as a specialized business logic layer. In order to be lazy, we use Java as a reference, called it The bean layer. At this point, the action is the most specialized wrapper layer, wrapping the bean's logic, then interacting with the view layer to produce the page, or outputting the data directly. So if I want to wrap the business process into a SOAP service, just add an action, without rewriting the business logic. If you have multiple views to display requirements, and you don't need to rewrite your business logic, simply extend the action. The following code shows how "this layer" is added.
First we create a new beans directory under the protected directory and then create a new loadbean.php file within the components to instantiate the Bean class and get the Bean object. The files under beans are named xxxbean.php, such as sitebean.php. Create a new configure.php file under beans. This file is a bean-loaded configuration file for IOC use. The new structure looks like this:
Site
|____resources
|____protected
|____config
|____controllers
|____models
|____views
|____beans
|____configure.php
|____sitebean.php
|____components
|____loadbean.php
|____framework
|____index.php
Beans is the place where the business logic is dedicated, where the action simply calls the business logic under beans and provides the output, without having to write the business logic code. To meet these requirements, we need to make a few changes to Yii's code. First find the cwebapplication.php file within the framework core, and its location is framework/web/cwebapplication.php. Add a Getbeanpath method within the file. The code is as follows:
Public Function Getbeanpath () {return $this->_controllerpath= $this->getbasepath (). Directory_separator. ' Beans '; }
Then locate the Createcontroller method within the file and locate the $classfile= $basePath. Directory_separator. $className. PHP '; This line of code, add the following code below it:
$beanPath = $owner->getbeanpath (); $beanName = Ucfirst ($id). ' Bean '; $classBean = $beanPath. Directory_separator. $beanName. PHP '; if (Is_file ($classBean)) {if (!class_exists ($beanName, False)) require ($classBean); }
In the third step, open the newly created loadbean.php file and add the following code:
class loadbean { private $objs; public function init () { $ Beanconfig = yii::app ()->basepath. ' \beans\configure.php '; $beans = require $beanconfig foreach ($beans as $bean) { if (! $this->objs[$bean] instanceof $bean. ' Bean ') { $class = $bean. ' Bean '; if (Class_exists ($class)) { $this->objs[$bean] = new $class ($bean); } } } } Public function obj ($name) { try{ if (array_key_exists ($name, $this- >OBJS)) { return $this->objs[$name]; }else{ throw new exception (' Bean name error '); } }catch ( exception $e) { echo $eGetMessage (); } }}
Fourth step, locate the protected/config/main.php file and add the following code:
' Beans ' =>array (' class ' = ' Loadbean ',),
Let the system load the Loadbean class added in the third step at initialization time.
Fifth step, find protected/beans/sitebean.php and add the following code:
Class Sitebean extends controller{public Function abc () {return123;}}
This ABC method is our business logic code.
Sixth step, find protected/beans/configure.php and add the following code:
Return Array (' Site ',);
This ' site ' is the ' site ' name of the Sitebean class.
The seventh step, implement the action method, find the protected/controllers/sitecontroller.php file (if not, can be created directly), the code is as follows:
Class Sitecontroller extends controller{public Function Actionindex () {Print_r (Yii::app ()->beans->obj ( ' Site ')->abc ()); }}
The action class does not directly interact with the Bean class, but instead communicates through the component class as an agent, separating the action from the bean.
At this point, the browser accesses the Http://yourdomain/index.php?r=Site/index to display 123. Here, we realize the separation of business logic and action, increase the expansibility and modification of the system, and the bean realizes the physical deployment independence. Form our four-tier architecture.
650) this.width=650; "src="/e/u261/themes/default/images/spacer.gif "alt=" Abc.zargo "class=" Editor-attachment " Style= "Background:url ("/e/u261/lang/zh-cn/images/localimage.png ") no-repeat center;border:1px solid #ddd;"/>
650) this.width=650; "src="/e/u261/themes/default/images/spacer.gif "alt=" Yii.zip "class=" Editor-attachment "style= "Background:url ("/e/u261/lang/zh-cn/images/localimage.png ") no-repeat center;border:1px solid #ddd;"/>
This article from the "Architect Road" blog, reproduced please contact the author!
Is the three-tier architecture design of the PHP framework really appropriate?