Home >Backend Development >PHP Tutorial >A brief discussion on PHP code design structure_PHP tutorial
After years of coding, all kinds of codes accompany me day and night. How to get along well with the code has not only become a reflection of career, but also a direct manifestation of the writer's skill.
How do you think about programs and code?
So let’s start with the program definition,
From the final presentation of the business, a program can be seen as a logical code mapping of real business requirements.
If you look at the logical structure of the program, the program is a combination of data structure and algorithm.
Looking at it this way, in order to meet more business needs and better meet these needs, more program codes are needed,
When the accumulation of program code reaches a certain amount, how to manage and organize the existing code will become an important issue. This is also a bottleneck for a programmer to explore from intermediate to higher levels after 3 to 5 years of programming.
Code that works when it meets your needs is good, and code that can be reused by multiple needs is even better.
With the development of software design, the trend of code collection and functional logic continues to be deposited and encapsulated becomes more and more clear.
It’s quick to use a tool well, but to master a design idea requires constant experimentation and improvement.
There is code specifically for processing data, and there is code specifically for processing presentation. How to manage and configure them in the business process? How can these logic be better encapsulated and reused.
In fact, for PHPer, these ideas are a bit troublesome when dealing with specific businesses. This is also the biggest advantage of PHP. It is very free and convenient. It has free, simple and casual basic syntax. It is so convenient that you don’t even need to consider memory resources. You can say hello quickly. ,
But this is also a major inherent disadvantage of PHP. There is no systematic and coherent design system,
When PHP was born, it was a single language that satisfied business needs. It did not have a very systematic design system and principles like JAVA. There are three most basic design principles in JAVA: 1. Global variables are not supported. 2. Don’t write universal classes. 3. The code must be class encapsulated.
The first and third principles of JAVA are grammatical restrictions, and the second principle is the standard for judging whether a JAVA programmer is an entry-level programmer. Relatively speaking, PHP does not have such grammatical design principle restrictions, but after contacting some big companies, there is really no system principle, hey,
But we can’t really have no principles in our design thinking!
PHP programs are actually as convenient as they come. The interpreter is very powerful and can block program codes that accommodate various ideas. As long as the syntax is OK, the code design does not matter.
Because the early PHP was too casual, it was easy to get started, and it was not necessary to effectively manage the code and conveniently reuse it.
With the development of PHP, PHP has bid farewell to the dynamic markup language in the PHP3~PHP4 era. However, due to the principle of upward compatibility, PHP is still a language with loose grammar,
Systematic programming principles have not yet been forced into the core of the language.
This does not mean that we do not need to use mature design ideas to improve and write our program code.
JAVA programming principles and code accumulation are the essence of JAVA, which become more and more obvious with the accumulation of time.
Introduce JAVA programming ideas into the PHP programming process. It's a great way to improve your PHP code.
1. Code hierarchical packaging
2. Files can be flexibly called and loaded, and resources can be created as needed
3. Smooth and anti-aging directory structure
Solving these problems can bring a lot of benefits to the programming process.
How to solve it?
Clear, effective, and consistent programming ideas can be achieved by disassembling and encapsulating MVC design ideas.
A program can be regarded as three logical blocks from the logical structure: Model, View and Controller.
The Model layer in JAVA implements the business logic in the system, which can usually be implemented using JavaBean or EJB. The View layer is used for interaction with users, usually implemented with JSP. The Controller layer is the communication bridge between Model and View, and is usually an extension of the router servlet to the application side.
But PHP does not have such clear divisions, so design ideas need to be integrated into the program code.
1. Program code class encapsulation
For an application requirement (ex: similar similar product page), first divide the requirement into 3 files: similar.controller.php; similar.model.php.similar.view.php
We can also see the purpose of the code in each file through the name. The remaining thing is to name the classes in each file.
Because they are different operation classes for one application, different category suffixes need to be added to each class,
For example similar.controller.php
//controller control program class The methods to complete this class are the process of each page of the program. Each method corresponds to a synchronous request page (to match the calling rules of the page)
class similar{
//Display of similar product pages
functio do_opensearch($_param){
//Request parameter filtering
//Request product data
//Process product data according to rendering rules
//Render product data to obtain and render html
//Display and render html
}
}
The corresponding request is
http://s.etao.com/similar/opensearch/
similar.model.php
//model data operation program class completes the encapsulation of data requests for this application and returns the structure analysis processing of the results
class similarMODEL{
}
similar.view.php
//model rendering operator class completes the data rendering encapsulation of this application and returns it to the processed
class similarVIEW{
Function view_getDetail($_goodDataArr){
return $html;
}
}
2. Class call
We have clearly encapsulated each logic and code in different files and classes. How to call it flexibly? PHP is an interpreted language. It does not have a compilation process like JAVA and C. It cannot enjoy the automatic connection function of compiled languages in the pre-compilation process.
In fact, the PHP interpreter is now aware of this problem, and has proposed the autoload method to solve it after 5.3.1. When the interpreter encounters a non-declared class or function, it will automatically run autoload to load it again. Report an error.
For details, see http://php.net/manual/en/language.oop5.autoload.php
But this is still a passive solution. An active dynamic loading solution is provided below. Add resource system mobilization category
Before explaining the use of this class, let’s take a look at our previous process of loading and using a class file:
File:similar.controller.php
require_once PATH."similar.model.php";
$sModelObj = new similarMODEL;
$goodsData = $sModelObj->getGoodsInfoByNid($nid);
This is called during the process. If called within the controller class, it needs to be written like this,
require_once PATH."similar.model.php";
class similar{
public $_modelObj;
function __construct(){
$this->_modelObj = new similarMODEL;
}
//Display of similar product pages
functio do_opensearch($_param){
//Request product data
$goodsInfoArr = $this->_modelObj->getGoodsInfoByNid($nid);
}
}//end class
If the controller class needs to use another MODEL, such as forest, ha3, etc., multiple in-class element variables must be declared. If you use PHP's variable transmission feature to create a resource scheduling class to uniformly load and schedule the required classes and declare them, it will be much easier to use. Let’s break down the design of this resource scheduling class in detail,
public static function getObj($_appName,$_typeStr='class') {
if($_typeStr=='class'){
$className = $_appName;
}else{
$className = $_appName.strtoupper($_typeStr);
}
//The resource object has been created. Return directly to use
if( isset(self::$_modelObjArr[$className]) && is_object(self::$_modelObjArr[$className]) ){
return self::$_modelObjArr[$className;
}
//Load file resource class file
$file = dirname(__FILE__)."{$_appName}/{$_appName}.{$_typeStr}.php";
if( file_exists($file) ){
require_once $file;
if( class_exists($className) ){
return self::_createObj($className);
}else{
$errStr = "no class {$className} in file {$file}"; //Class name error
}
} else {
$errStr = "no class file {$file}"; //Class file error
}
self::_showErr($errStr);
}
//Create resource object
public static function _createObj($_className){
if( isset(self::$_modelObjArr[$_className]) && is_object(self::$_modelObjArr[$_className]) ){
return self::$_modelObjArr[$_className];
}else{
self::$_modelObjArr[$_className] = new $_className();
return self::$_modelObjArr[$_className];
}
}
//Error message
public static function _showErr($_errTypeStr=''){
echo $_errTypeStr; exit;
//errorlog($_errTypeStr);
}
}//end class
Use the Box resource scheduling class instead and load the class program
File:similar.controller.php
/**
* Load the specified type of class program
**/
class Box {
//Declare an in-process resource object pool
public static $_modelObjArr;
//Get a resource object
class similar{
function __construct(){
}
//Display of similar product pages
functio do_opensearch($_param){
//Request product data
$goodsInfoArr = Box::getObj('similar','model')->getGoodsInfoByNid($nid);
$html = Box::getObj('similar','view')->view_getDetail($goodsInfoArr);
//Other encapsulated data logic
$hotHtml = $this->_getHotHtml();
}
function do_search($_param){
$goodsInfoArr = Box::getObj('similar','model')->getGoodsInfoByNid($nid);
$html = Box::getObj('similar','view')->view_getDetail($goodsInfoArr);
}
function _getHotHtml(){
$hotInfoArr = Box::getObj('similar','model')->getGoodsInfoByNid($nid);
$html = Box::getObj('similar','view')->view_getDetail($goodsInfoArr);
return $hotInfoArr;
}
}//end class
In this way, the "similar.model.php"; file will only be loaded once in a response process, and similarMODEL will only be created once,
Call at any time. There is no need to declare in advance, no need to consider repeated loading, and repeated creation.
Box solves the problem of calling and creating resources between classes.
So how to make a function in a controller class file run? We need a request dispatch class Bin.
Previously, our request responses were all completed through the io model of websearch. Map the requested path to the actual file.
For example:
For files like xxxx.taobao.com/similar/opensearch/index.php or xxx.etao.com/similar/opensearch.php, websearch will replace the host with the path of the actual file system.
In this way, external programs can scan our directories in various ways. If they are not careful, some common methods will be exposed, such as ex:xxxx.taobao.com/tools/info.php, etc., which has hidden risks.
Of course, adding some filtering conditions can shield such problems, but it will increase or decrease the logic of the webserver. Once there are changes, the conf of the webserver will be changed. trouble. Let’s simply use the webserver to package and unpack io and http in a down-to-earth manner,
Let the app server filter and flexibly configure request calls. All accesses are mapped (rewitre) to host/dispatch.php in the webserver, and scheduling and distribution are implemented by the Bin class. Implement a single entry call structure for application logic.
dispatch.php completes a platform allocation, performance monitoring, configuration loading, application startup, type input (synchronous, asynchronous, PC, mobile), and other platform-level functions.
The Bin class needs the following functions: parse the request, pass the environment variables passed by the webserver to the actual processing application of the response to complete the decomposition, propose similar application names, opensearch method names,
There are also GET and POST request parameters, assembled into a request parameter array,
1
2 $this->_paramArr = explode( '/', trim(strtok( urldecode($_SERVER["REQUEST_URI"]),'?'),'/'));
$this->_paramArr = array_merge($this->_paramArr,$_GET);
In this way $this->_paramArr[0] is the appname application name
In this way $this->_paramArr[1] is the function method name www.2cto.com
The platform process can load the appname.class.php file and execute the appname->do_function($this->_paramArr); method.
This also supports parameters such as /similar/opensearch/sort/, sort is a parameter of $this->_paramArr[2]
If $this->_paramArr[0] is equal to ajax, it means that this is an asynchronous request initiated by js,
What needs to be loaded is appname.ajax.php, and execute appnameAJAX->ajax_function();
Separate synchronous and asynchronous requests into files. Reduce the memory usage of loading large files.
It is also possible to physically classify accessible directories and application directories, rendering scanners useless.
For example:
/home/website/host/ This directory only contains one file, index.php, and some rendering files such as css, js, and images that are not added to CDN. Set the documentroot or laction of the webserver in this directory
/home/website/app/ This directory is used to store the written class program files and configurations. The class program files in the app directory are loaded by the /host/index.php program
One application is easy to handle, but what should we do with a bunch of applications? Let's talk about the directory structure of multiple applications.
3. Directory structure (anti-aging is very important)
The design concepts of PHP are very few, and there is not even the concept of a package. We had to use catalogs to package the package concept ourselves. Introduce the role of the directory structure from the access structure, development structure, and deployment structure.
3a. Access structure
The access directory host and the application directory app can be regarded as a website. The applications under this site can be like this
It can be created like this
/website/host
/website/app/similaer
/website/app/cmp
/website/app/srp
/website/app/…..
If the management tool can also create another directory under the website
/website/admin/firebox
/website/admin/seoAny
In this way, all requests will go to /website/host/index.php and index.php will load the response logic program according to the request rules.
There is a system directory parallel to /webiste/host, /website/system/, where platform files such as box.class.php, bin.class.php, base.class.php and so on are stored.
The execution process of a response is
webserver query ->[ /website/host/index.php include /website/system/box,bin,base (application architecture)] Platform -> [ /website/app/ (application process) | /website/admin/ ]Page
3b. Development structure
During the development and maintenance process, there will be some similar PHP library files, such as curl communication, xml parsing, log, timer, template (appview), and other self-developed class programs, as well as third-party class libraries such as smarty and big2gb.
All projects are common, including price comparison, main search, and My Taobao. Then you can create a PHPLIBS directory on par with the website
/website/host/
/website/app/
/website/system/
/PHPlibs/etao/ own class library
/PHPlibs/other/ Third-party libraries
One svn for each website
PHPlibs/an independent svn is maintained by dedicated personnel, which is faster, faster, cheaper and more professional
Separate the template file from website/ and create a
webtemplate/directory Share an svn with ued students, and let ued students write template files according to the rules of the template class in the previous paragraph. Stored in directories by application.
Such as:
webtemplate/srp
webtemplate/cmp
webtemplate/opensearch
webtemplate/frame presents templates uniformly, page header and footer
webtemplate/…..
The program in website/app calls the above template file through the template class method.
At the same time, during the development and maintenance process, you will also encounter php scripts that require shell execution, such as regularly generating public page headers and tails, regularly fetching epid data from the mysql library, etc. Or make an algorithm program temporarily.
Then we can
Add the app.sh.php program file to the related applications of /website/app/,
Such as
/website/app/similar/similar.sh.php The class program similarSH for this file is passed
/website/script/run.php to execute. script/run.php is a shell-side controller that responds to CLI requests, and host/index.php is a web-side controller that responds to CGI requests
You can also wrap a debug.bat file outside script/run.php, which can be already in DOS, or wrap a debug.sh program and then debug it interactively under the shell.
Specific reference code
There are also some programs that process files, such as the public page header and footer files of the PHP template converted from vm files. There will be a webdata file parallel to the website,
/website/….
/webdata/pageframe and other directories, call
directly in the app
3c. Deployment structure
Checkout separately through online script
/website/
/PHPlibs/
/webtemplate/ svn resource library
Then package the rpm and push it online.
When going online alone, the online script configuration is also used to check out the corresponding files and push them to the front-end production machine.
4. Code specifications
Regarding code format specifications, everyone has been actively discussing it for a long time before reading this.
For code format specifications, we can configure it in the IDE, use it automatically, and cultivate the habit of writing easy-to-read code through constant reviews and reminders.
Code design specifications need to be specified according to the architecture and adhere to the implementation.
The code design discussed below is based on the resource calling and request allocation just mentioned.
4a, About the catalog
//Application
/website/app/….
//External access directory
/website/host/index.php
/website/host/css
/website/host/js
/website/host/images
//Platform system files
/website/host/images
//Debug and maintain script
/website/script/
//Template library corresponds to the directory under /website/app/
/webtemplate/….
//Program library
/PHPlibs/
//Data file directory
/webdata
There is nothing to say, everyone understands.
4b, About the file
The naming convention of files mainly specifies internal calls and request calls
website/app/appname/appname.apptype.php
apptype: class,model,view,ajax,api,sh,….
Call:
Box::getObj(appname,apptype)->function();
The appname.class.php file is the controller file, and the methods in the class perform synchronous request responses.
The appname.ajax.php file is also a controller file, and the methods in the class make asynchronous request responses.
The appname.sh.php file is also a controller file, and the methods in the class respond to the CLI.
The appname.api.php file can be regarded as a controller file. The methods in the class are encapsulation of a common or common logic, such as obtaining the full path of an image.
4c, about classes and methods
Class naming:
Except for those in class files that are directly named with appname, other class files are named with appname+APPTYPE, and APPTYPE needs to be capitalized. Easy to make grammatical distinctions.
Method naming:
Add a prefix to the method declaration to explain the function of the method. For example, add html_getSimilarList() to the method in the view class, add db_getData() to the model method to get it from the database, file_getData() to get it from the file, and url_getData() to get it from the engine or remote end.
4d, about variables and comments
In-class variables and parameter entry variables are prefixed with _ to distinguish them from local variables used in the process to increase readability.
class similar{
public $_obj;
function do_getpage($_param){
}
}
File annotation = class annotation
Add at the beginning of the file to explain the function of this class:
/**
* @package:
* @access: MixrenSystemBox.inc.php
* Summary: System application template controls the allocation program; completes request analysis; module loading; request processing (execution);
* @Created: Fri Dec 25 16:41:02 CST 2009
* @Author: Zhurong
* @Generator: EditPlus2 & Dreamweaver & Zend & eclipse
*/
Method comments
/**
* Initialization request
*param parameter description
**/
private function _parseApp(){
$this->_queryStr = urldecode($_SERVER["REQUEST_URI"]);
$this->_paramArr = explode( '/', trim(strtok($this->_queryStr,'?'),'/'));
//Assign request module
$appName = DEFAULT_APP_NAME;
$this->_className = $appName;
$this->_appFile = APP_PATH . "{$appName}/{$appName}.controller.php";
$this->_method = empty($this->_paramArr[0]) ? DEFAULT_APP_METHOD : $this->_paramArr[0];
$this->_method = "do_{$this->_method}";
}
Class end comment
class Bin{
}//end class
Add comments to the main processes and algorithms to facilitate maintenance and reading.
Before going online, the file will be commented using php -w through the online script, so long comments will not occupy the loading memory during program execution.
5. Code monitoring
Dedicated code scanning script.
Scan the directories, files, methods, and comments under /website/app/.
Report, how many application directories; how many synchronous response classes; how many asynchronous response classes; how many synchronous pages; how many asynchronous interfaces; how many logical interfaces; how many model interfaces; how many templates; code comment rate of each file; etc.
Based on the above design ideas, a tree structure design program architecture is established from the folder-"segmented class file-" function module method to maximize the realization of the CAP principles consistency (consistency), availability (reusability), and Partition (effective division) )
Let PHP code be better accumulated.
Templates (pure html files, rendering configuration), program data configuration files are loaded into the program, instead of loading the program into html for segment by segment interpretation and execution.
Excerpted from Search Technology Blog—Taobao