Compile your own PHPMVC framework example tutorial

Source: Internet
Author: User
Model-View-Controller (MVC) is a software architecture Model in software engineering. the software system is divided into three basic parts: Model and View) and Controller ). 1. what is MVC?


Model-View-Controller (MVC) is a software architecture Model in software engineering. the software system is divided into three basic parts: Model and View) and Controller ).
The purpose of the MVC pattern is to implement a dynamic program design, simplify subsequent modifications and extensions of the program, and make reuse of a part of the program possible. In addition, this mode simplifies the complexity to make the program structure more intuitive. The software system also gives the functions of each basic part through the separation of its basic parts.
In short,
Model-manages all database-related logic. The model provides an abstraction layer for connecting to and operating databases.
Controller-responsible for all business logic, such as if/else logic.
View-displays the interface, such as HMTL, XML, and JSON.
Php mvc tutorial
2. why should I develop the MVC framework by myself?


There are a large number of excellent MVC frameworks available on the network. this tutorial is not intended to develop a comprehensive and ultimate MVC framework solution, it is a good opportunity to learn PHP from the inside. in this process, you will learn object-oriented programming and MVC design patterns, and learn some precautions in development.
More importantly, you can have full control over your framework and integrate your ideas into your development framework. Although not always done well, you can develop functions and modules in your way.
3. start to develop your own MVC framework.


3.1 Directory preparation


Before starting development, let's first set up the project. assume that the project we created is todo, and the MVC framework can be named FastPHP, the next step is to set the directory structure first.
Php mvc simple directory
Although none of the above directories will be used in this tutorial, it is necessary to set the program directory at the beginning to make the program more extensible in the future. The role of each directory is described as follows:
Application-application code
Config-program configuration or database configuration
Fastphp-core framework Directory
Public-static file
Runtime-temporary data directory
Scripts-command line tool
3.2 code specification


After the directory is set, we need to specify the code specifications:
MySQL table names must be in lower case, such as: item, car
The module name (Models) must start with an uppercase letter and add "Model" after the name, such as ItemModel and CarModel.
The first letter of the Controller must be capitalized, and the "Controller" should be added to the name, for example, ItemsController and CarsController.
The view deployment structure is "controller name/behavior name", for example, item/view. php, car/buy. php.
The above rules are used to better call each other in the program. Next we will start the real php mvc programming.
3.3 redirection


Redirect all data requests to the index. php file and create a new. htaccess file under the todo Directory. the file content is:
RewriteEngine On # ensure that the request path is not a file name or directory RewriteCond % {REQUEST_FILENAME }! -F RewriteCond % {REQUEST_FILENAME }! -D # redirect all requests to index. php? Url = PATHNAME RewriteRule ^ (. *) $ index. php? Url = $1 [PT, L]
The main reasons for doing so are:
The program has a single entry;
All other programs except static programs are redirected to index. php;
It can be used to generate SEO-friendly URLs. if you want to better configure the URLs, you may need URL routing later. we will not introduce it here.
3.4 Portal file


After completing the above operations, you should know what we need to do. that's right! Add the index. php file to the public directory. the file content is:
// The Application Directory is the current directory define ('app _ path', _ DIR __. '/'); // enable the DEBUG mode define ('app _ debug', true); // load the framework require '. /fastphp/FastPHP. php ';
Note: In the above PHP code, no PHP end symbol is added "?> ", The main reason for this is that for files with only PHP code, the end mark ("?> ") It is better not to exist. PHP does not need an ending symbol. if you do not add an ending symbol, you can avoid adding additional injected content to the end to make the program safer.
3.5 configuration file and master request


In index. php, we initiate a request to fastphp. php in the FastPHP folder. what does the FastPHP. php startup file contain?
// Initialize the constant defined ('root') or define ('root', _ DIR __.'/');
Defined ('app _ path') or define ('app _ path', dirname ($ _ SERVER ['script _ filename']). '/');
Defined ('app _ debug') or define ('app _ debug', false );
Defined ('config _ path') or define ('config _ path', APP_PATH. 'config /');
Defined ('runtime _ path') or define ('runtime _ path', APP_PATH. 'runtime/'); // class file extension const EXT = '. class. php'; // contains the configuration file require APP_PATH. 'config/config. php'; // contains the core framework class require ROOT. 'core. php'; // instantiate the core class $ fast = new Fast;
$ Fast-> run ();
The above files can be directly stored in index. php files, constants can also be directly stored in index. php defines that the reason we do this is to make it easier to manage and expand in the future, therefore, the program that needs to be loaded and run at the beginning should be put into a separate file for reference.
Let's take a look at the config. php file in the config file. The main function of this file is to set some program configuration items and database connections. The main content is:
/** Variable configuration **/define ('Db _ name', 'Todo ');
Define ('Db _ user', 'root ');
Define ('Db _ password', 'root ');
Define ('Db _ host', 'localhost ');
It should be said that config. php involves not much content, but some basic database settings. let's take a look at how to write the shared framework entry file Core. php under fastphp.
/**
* FastPHP core framework
*/Class Fast {// run the program function run (){
Spl_autoload_register (array ($ this, 'loadclass'); $ this-> setReporting (); $ this-> removeMagicQuotes (); $ this-> unregisterGlobals (); $ this-> callHook ();
} // Main request method. The main purpose is to split the URL request function callHook () {if (! Empty ($ _ GET ['URL']) {
$ Url = $ _ GET ['URL'];
$ UrlArray = explode ("/", $ url); // Get the controller name $ controllerName = ucfirst (empty ($ urlArray [0])? 'Index': $ urlArray [0]);
$ Controller = $ controllerName. 'controller'; // Obtain the action name array_shift ($ urlArray );
$ Action = empty ($ urlArray [0])? 'Index': $ urlArray [0]; // Obtain the URL parameter array_shift ($ urlArray );
$ QueryString = empty ($ urlArray )? Array (): $ urlArray;
} // Processing with empty data $ action = empty ($ action )? 'Index': $ action;
$ QueryString = empty ($ queryString )? Array (): $ queryString; // instantiate the controller $ int = new $ controller ($ controllerName, $ action); // if the controller and action exist, this call and pass in the URL parameter if (int) method_exists ($ controller, $ action )){
Call_user_func_array (array ($ int, $ action), $ queryString );
} Else {exit ($ controller. "The controller does not exist ");
}
} // Check the development environment function setReporting () {if (APP_DEBUG = true ){
Error_reporting (E_ALL );
Ini_set ('display _ errors ', 'on ');
} Else {
Error_reporting (E_ALL );
Ini_set ('display _ errors ', 'off ');
Ini_set ('log _ errors ', 'on ');
Ini_set ('error _ log', RUNTIME_PATH. 'logs/error. log ');
}
} // Delete the sensitive character function stripSlashesDeep ($ value ){
$ Value = is_array ($ value )? Array_map ('stripslashesdeep ', $ value): stripslashes ($ value); return $ value;
} // Detect sensitive characters and delete function removeMagicQuotes () {if (get_magic_quotes_gpc ()){
$ _ GET = stripSlashesDeep ($ _ GET );
$ _ POST = stripSlashesDeep ($ _ POST );
$ _ COOKIE = stripSlashesDeep ($ _ COOKIE );
$ _ SESSION = stripSlashesDeep ($ _ SESSION );
}
} // Check the custom global variable (register globals) and remove the function unregisterGlobals () {if (ini_get ('register _ globals ')){
$ Array = array ('_ SESSION', '_ post',' _ get', '_ cookier',' _ request', '_ server',' _ env ', '_ Files'); foreach ($ array as $ value) {foreach ($ GLOBALS [$ value] as $ key => $ var) {if ($ var ===$ GLOBALS [$ key]) {unset ($ GLOBALS [$ key]);
}
}
}
}
} // Automatically load the controller and model class static function loadClass ($ class ){
$ Frameworks = ROOT. $ class. EXT;
$ Controllers = APP_PATH. 'application/controllers/'. $ class. EXT;
$ Models = APP_PATH. 'application/models/'. $ class. EXT; if (file_exists ($ frameworks) {// load the Framework Core class include $ frameworks;
} Elseif (file_exists ($ controllers) {// load the application controller class include $ controllers;
} Elseif (file_exists ($ models) {// load the application model class include $ models;
} Else {/* error code */}
}


}
The following describes the main request method callHook (). First, we want to see that our URL will look like this:
Yoursite.com/controllerName/actionName/queryString
CallHook () is used to obtain the url from the global variable $ _ GET ['URL'] and divide it into three parts: $ controller, $ action, and $ queryString.
For example, if the URL is todo.com/item/view/1/first-item
$ Controller: items
$ Action: view
Query String: array (1, first-item)
After splitting, a new controller is instantiated: $ Controller. 'controller' (where "." is a hyphen) and its method $ action is called.
3.6 Controller/Controller base class


The next operation is to create the base class required by the program in fastphp, including the base class of the controller, model, and view.
The new Controller base class is Controller. class. php. The main function of the Controller is General scheduling. the specific content is as follows:
/**
* Controller base class
*/Class Controller {protected $ _ controller; protected $ _ action; protected $ _ view; // Constructor, initialize attributes, and instantiate the corresponding model function _ construct ($ controller, $ action) {$ this-> _ controller = $ controller; $ this-> _ action = $ action; $ this-> _ view = new View ($ controller, $ action );
} Function set ($ name, $ value) {$ this-> _ view-> set ($ name, $ value );
} Function _ destruct () {$ this-> _ view-> render ();
}


}
The Controller class enables communication between all controllers, models, and views. When executing the destructor, we can call render () to display the view file.
3.7 Model base class


The new Model base class is Model. class. php. The Model base class Model. class. php code is as follows:
Class Model extends SQL {protected $ _ model; protected $ _ table; function _ construct () {// connect to the database $ this-> connect (DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); // Convert Model + model to Model name // Obtain the name of the class to which the object belongs $ this-> _ model = get_class ($ this ); $ this-> _ model = rtrim ($ this-> _ model, 'model '); // The database table name is consistent with the class name $ this-> _ table = strtolower ($ this-> _ model );
} Function _ destruct (){
}
}
Considering that the model needs to process the database, a database base class SQL. class. php is created separately. The model base class inherits SQL. class. php. the code is as follows:
Class SQL {protected $ _ dbHandle; protected $ _ result;/** connect to database **/function connect ($ address, $ account, $ pwd, $ name) {$ this-> _ dbHandle = @ mysql_connect ($ address, $ account, $ pwd); if ($ this-> _ dbHandle! = 0) {if (mysql_select_db ($ name, $ this-> _ dbHandle) {return 1;
} Else {return 0;
}
} Else {return 0;
}
}/** Disconnect from database **/function disconnect () {if (@ mysql_close ($ this-> _ dbHandle )! = 0) {return 1;
} Else {return 0;
}
}/** Query all **/function selectAll (){
$ Query = 'select * from ''. $ this-> _ table. '''; return $ this-> query ($ query );
}/** Query by condition (id) **/function select ($ id ){
$ Query = 'select * from ''. $ this-> _ table. ''Where 'id' = \''. mysql_real_escape_string ($ id ). '\ ''; return $ this-> query ($ query, 1 );
}/** Delete by condition (id) **/function delete ($ id ){
$ Query = 'delete from ''. $ this-> _ table. ''Where 'id' = \''. mysql_real_escape_string ($ id ). '\ ''; return $ this-> query ($ query );
}/** Custom SQL query **/function query ($ query, $ singleResult = 0) {$ this-> _ result = mysql_query ($ query, $ this-> _ dbHandle); if (preg_match ("/select/I", $ query )){
$ Result = array ();
$ Table = array ();
$ Field = array ();
$ TempResults = array ();
$ NumOfFields = mysql_num_fields ($ this-> _ result); for ($ I = 0; $ I <$ numOfFields; ++ $ I) {array_push ($ table, mysql_field_table ($ this-> _ result, $ I ));
Array_push ($ field, mysql_field_name ($ this-> _ result, $ I ));
} While ($ row = mysql_fetch_row ($ this-> _ result) {for ($ I = 0; $ I <$ numOfFields; ++ $ I) {$ table [$ I] = ucfirst ($ table [$ I]); $ tempResults [$ table [$ I] [$ field [$ I] = $ row [$ I];} if ($ singleResult = 1) {mysql_free_result ($ this-> _ result); return $ tempResults;
}
Array_push ($ result, $ tempResults );
}
Mysql_free_result ($ this-> _ result); return ($ result );
}


}/** Get the number of records **/function getNumRows () {return mysql_num_rows ($ this-> _ result );
}/** Release query resource **/function freeResult (){
Mysql_free_result ($ this-> _ result );
}/** Get error message **/function getError () {return mysql_error ($ this-> _ dbHandle );
}


}
It should be said that SQL. class. php is the core part of the framework. Why? Because of this, we have created an SQL abstraction layer, which can greatly reduce the programming work of the database. The connect () and disconnect () methods are relatively simple and are not described much. the focus is on Query queries. Suppose we have the following SQL query statement:
SELECT table1.field1, table1.field2, table2.field3, table2.field4 FROM table1, table2 WHERE...
If the preceding SQL base class is used, the first task is to select the fields to be output and the corresponding data table, and then put them in the array, $ field and $ table use the same index value. In the preceding example, they are as follows:
$ Field = array (field1, field2, field3, field4 );
$ Table = array (table1, table1, table2, table2 );
The script will show all data rows and convert the data table into a model name (for example, remove the plural and uppercase letters ). The query result is stored in a multi-dimensional array and then returned in the format of $ var ['modelname'] ['fieldname']. In this way, these elements can be easily used in views.
3.8 View class


View. class. php:
/**
* View base class
*/Class View {protected $ variables = array (); protected $ _ controller; protected $ _ action; function _ construct ($ controller, $ action) {$ this-> _ controller = $ controller; $ this-> _ action = $ action;
}/** Variable setting method **/function set ($ name, $ value) {$ this-> variables [$ name] = $ value;
}/** Display **/function render (){
Extract ($ this-> variables );
$ DefaultHeader = APP_PATH. 'application/views/header. php ';
$ DefaultFooter = APP_PATH. 'application/views/footer. php ';
$ ControllerHeader = APP_PATH. 'application/views/'. $ this-> _ controller.'/header. php ';
$ ControllerFooter = APP_PATH. 'application/views /'. $ this-> _ controller. '/footer. php '; // page header file if (file_exists ($ controllerHeader) {include ($ controllerHeader );
} Else {include ($ defaultHeader );
} // Page content file include (APP_PATH. 'application/views /'. $ this-> _ controller. '/'. $ this-> _ action. '. php '); // if (file_exists ($ controllerFooter) {include ($ controllerFooter );
} Else {include ($ defaultFooter );
}
}


}
In this way, the core php mvc framework is compiled. next we will write an application to test the framework function.
4 Applications


4.1 Database deployment


Create a new todo database in SQL. use the following statement to add the item data table and insert two records:
Create table 'items '(
'Id' int (11) not null auto_increment,
'Item _ name' varchar (255) not null,
Primary key ('id ')
); Insert into 'items 'VALUES (1, 'Hello World.'); insert into 'items 'VALUES (2, 'lets' go! ');
4.2 Deployment Model


Then, create an ItemModel. php model in the models directory. the content is as follows:
Class ItemModel extends Model {/** add data **/function add ($ value ){
$ Query = 'Insert ''. $ this-> _ table. ''(item_name) values (\''. mysql_real_escape_string ($ value ). '\') '; return $ this-> query ($ query );
}/** Add data **/function update ($ id, $ value ){
$ Query = 'update ''. $ this-> _ table. ''set item_name = \''. mysql_real_escape_string ($ value ). '\ 'where' ID' = \''. mysql_real_escape_string ($ id ). '\ ''; return $ this-> query ($ query );
}
}
The model content is empty. Because the Item Model inherits the Model, it has all the functions of the Model.
4.3 deploy the controller


Create an ItemsController. php controller in the controllers Directory. the content is as follows:
Class ItemController extends Controller {// homepage method, test framework custom DB query function index (){
$ Item = new ItemModel; $ this-> set ('title', 'all table'); $ this-> set ('Todo ', $ item-> query ('select * from item '));
} // Add record, test framework DB record creation (Create) function add (){
$ Value = $ _ POST ['value'];
$ Item = new ItemModel; $ this-> set ('title', 'added successfully'); $ this-> set ('Todo ', $ item-> add ($ value ));
} // View the record. Read (Read) function view ($ id = null, $ name = null ){
$ Item = new ItemModel; $ this-> set ('title', 'viewing '. $ name); $ this-> set ('Todo ', $ item-> select ($ id ));
} // Update record, test framework DB record update function Update (){
$ Id = $ _ POST ['id'];
$ Value = $ _ POST ['value'];
$ Item = new ItemModel; $ this-> set ('title', 'modified successfully'); $ this-> set ('Todo ', $ item-> update ($ id, $ value ));
} // Delete record, test framework DB record deletion (delete) function Delete ($ id = null ){
$ Item = new ItemModel; $ this-> set ('title', 'deleted successfully'); $ this-> set ('Todo ', $ item-> delete ($ id ));
}


}
4.4 deployment view


In the views Directory, create the header and footer templates header. php and footer. php. the content is as follows.
Header. php, content:
Echo $ title?> Title>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.