Use PHP to build your own MVC framework

Source: Internet
Author: User
Tags learn php php foreach

First, what is MVC

The MVC pattern (model-view-controller) is a software architecture model in software engineering, which divides the software system into three basic parts: model, view and controller.

The purpose of the MVC pattern is to implement a dynamic program design that simplifies the subsequent modification and expansion of the program, and makes it possible to reuse a part of the program. In addition, this mode makes the program structure more intuitive by simplifying the complexity. By separating the basic parts of the software system, it also gives the functions of each basic part. Professionals can be grouped by their own expertise:

(Controller controllers)-responsible for forwarding requests and processing requests.

(views view) – Graphical interface design for interface designers.

(model) – The functions that programmers write programs (implementation algorithms, etc.), data management by database specialists, and database design (which can be implemented in specific functions).

The model data model is used to encapsulate data related to the business logic of the application and how to handle the data. "Model" has the right to direct data access, such as access to the database. "Model" does not depend on "view" and "Controller", that is, the model does not care how it will be displayed or how it is manipulated. However, changes in the data in the model are generally advertised through a refresh mechanism. To implement this mechanism, the views that are used to monitor this model must be registered in advance on this model, so that the view can understand the changes that have occurred on the data model.

The view view layer is capable of achieving a purposeful display of data (in theory, this is not required). There is generally no logic on the program in the view. To implement the Refresh feature on the view, the view needs to access the data model it monitors, so it should be registered with the data it is monitoring beforehand.

Controller controllers play an organizational role across different levels to control the flow of applications. It handles the event and responds. An "event" includes the user's behavior and changes on the data model.

Second, why should we develop the MVC framework

There are a number of excellent MVC frameworks available on the Web, and this tutorial is not intended to develop a comprehensive, ultimate MVC framework solution, but to see it as a good opportunity to learn PHP from the inside, and in the process you will learn object-oriented programming and design patterns, and learn some of the considerations of openness.

More importantly, you can take full control of your framework and incorporate your ideas into your development framework. Although not necessarily a good one, you can develop features and modules in your own way.

Iii. start to develop your own MVC framework

Before we start development, let's set up the project first, assuming that the project we're building is Todo, then the next first step is to set up the directory structure first.

Although all of the above directories are not used in this tutorial, it is necessary to set up the program directory at the outset in order to extend the program's extensibility. Here's what each directory is about:

application– Store Program code

config– Store program configuration or database configuration

db– used to store database backup content

library– Storing frame Codes

public– Storing static files

scripts– storing command-line tools

tmp– Storing temporary data

After the catalog is set up, we'll come up with some code specifications:

MySQL table names need to be lowercase and in plural form, such as Items,cars

The module name (Models) needs to be capitalized in the first letter and in the singular mode, such as Item,car

The controller (Controllers) needs to be capitalized, in plural form and with "Controller" in the name, such as Itemscontroller, Carscontroller

The view (views) takes the plural form and adds the behavior later as a file, such as: items/view.php, cars/buy.php

Some of the rules above are designed to make it easier to call each other in a program clock. The next step is to start the real coding.

The first step is to redirect all requests to the public directory, and the solution is to add a. htaccesss file under the Todo file with the following file contents:

<ifmodule mod_rewrite.c>rewriteengine onrewriterule    ^$    public/    [L]rewriterule    (. *) public/$ 1    [l]</ifmodule>

After we redirect all requests to the public directory, we need to redirect all the data requests to the index.php file under public, so we need to create a new. htaccess file under the public folder with the following file contents:

<ifmodule mod_rewrite.c>rewriteengine on# If the file exists, direct access to the directory is not performed Rewriterulerewritecond%{request_filename}!-f# If the directory exists for direct access to the directory without Rewriterulerewritecond%{request_filename}!-d# Rewrite all other URLs to Index.php/urlrewriterule ^ (. *) $ Index.php?url=$1 [pt,l]</ifmodule>

The main reasons for doing this are:

You can have a single entry for the program, redirecting all programs except static programs to index.php;

can be used to generate SEO-conducive URLs, want to better configure the URL, late may need URL routing, here do not introduce.

Finish the above operation, you should know what we need to do, yes! In the public directory, add the index.php file with the following file contents:

<?php    define (' DS ', directory_separator);    Define (' ROOT ', DirName (dirname (__file__)));    $url = $_get[' url '];    Require_once (ROOT. DS. ' Library '. DS. ' bootstrap.php ');

Note that the PHP code above does not add the PHP end symbol "?>", the main reason for this is: For files containing only PHP code, the end flag ("?>") Best not exist, PHP itself does not need to end the symbol, Not adding a closing symbol can largely prevent the end from being added with additional injected content, making the program more secure.

In index.php, we made a request to bootstrap.php under the Library folder, so what does bootstrap.php include in this boot file?

<?php    require_once (ROOT. DS. ' Config '. DS. ' Config.php ');    Require_once (ROOT. DS. ' Library '. DS. ' Shared.php ');

The above files can be directly referenced in the index.php file, we do so for the later management and expansion of the more convenient, so the need to load the run at the beginning of the program is unified into a separate file reference.

First look at the config file under config. php file, the main role of the file is to set some program configuration items and database connection, the main content is:

<?php    # Sets whether the development status is    define (' Development_environment ', true);    # Set the data required for database connection    define (' db_host ', ' localhost ');    Define (' db_name ', ' todo ');    Define (' Db_user ', ' root ');    Define (' Db_password ', ' root ');

It should be said that there is not much content involved in config.php, but some of the basic data settings, and then look at the library under the common file shared.php should be how to write.

<?php/* Check for development environment and set whether error log is logged */function setreporting () {if (development_environment = = 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 ', ROOT. Ds. ' TMP '. Ds. ' Logs '. Ds.        ' Error.log '); }/* Detect sensitive character escapes (Magic Quotes) and remove them */function Stripslashdeep ($value) {$value = Is_array ($value)? Array_map ('        Stripslashdeep ', $value): Stripslashes ($value);    return $value;            } function Removemagicquotes () {if (GET_MAGIC_QUOTES_GPC ()) {$_get = Stripslashdeep ($_get);            $_post = Stripslashdeep ($_post);        $_cookie = Stripslashdeep ($_cookie);           }/* Detects global variable settings (register globals) and removes them */function unregisterglobals () {if (Ini_get (' register_globals ')) { $array = Array (' _session ', ' _post ', ' _get ', ' _cookie ',' _request ', ' _server ', ' _env ', ' _files '); foreach ($array as $value) {foreach ($GLOBALS [$value] as $key = + $var) {if ($var = = = $                  globals[$key]) {unset ($GLOBALS [$key]);        }}}}}/* Master request method, main purpose split URL request */function Callhook () {global $url;        $urlArray = Array ();        $urlArray = Explode ("/", $url);        $controller = $urlArray [0];        Array_shift ($urlArray);        $action = $urlArray [0];        Array_shift ($urlArray);        $queryString = $urlArray;        $controllerName = $controller;        $controller = Ucwords ($controller);        $model = RTrim ($controller, ' s ');        $controller. = ' Controller ';        $dispatch = new $controller ($model, $controllerName, $action);        if ((int) method_exists ($controller, $action)) {Call_user_func_array (Array ($dispatch, $action), $queryString); } else {/* Generate error code */}}/* Auto Load Controller and model */function __autoload ($className) {if (file_exists ROOT. Ds. ' Library '. Ds. Strtolower ($className). '. class.php ') {require_once (ROOT. Ds. ' Library '. Ds. Strtolower ($className).        '. class.php '); } else if (File_exists (ROOT. Ds. ' Application '. Ds. ' Controllers '. Ds. Strtolower ($className). '. php ') {require_once (ROOT. Ds. ' Application '. Ds. ' Controllers '. Ds. Strtolower ($className).        '. php '); } else if (File_exists (ROOT. Ds. ' Application '. Ds. ' Models '. Ds. Strtolower ($className). '. php ') {require_once (ROOT. Ds. ' Application '. Ds. ' Models '. Ds. Strtolower ($className).        '. php ');    } else {/* generates error code */}} setreporting ();    Removemagicquotes ();    Unregisterglobals (); Callhook ();

The next step is to build the base class needed for the program in the library, including the base class for the controller, model, and view.

The new Controller base class is controller.class.php, the main function of the controller is the total scheduling, the specific content is as follows:

<?php    class Controller {        protected $_model;        protected $_controller;        protected $_action;        protected $_template;        function __construct ($model, $controller, $action) {            $this->_controller = $controller;            $this->_action = $action;            $this->_model = $model;            $this $model =& new $model;            $this->_template =& New Template ($controller, $action);        }        function set ($name, $value) {            $this->_template->set ($name, $value);        }        function __destruct () {            $this->_template->render ();        }    }

The new Controller base class is model.class.php, considering that the model needs to process the database, so you can create a new database base class sqlquery.class.php, the model to inherit sqlquery.class.php.

Create a new sqlquery.class.php with the following code:

<?php class SQLQuery {protected $_dbhandle;        protected $_result; /** Connection 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; }}/** Interrupt database connection **/function disconnect () {if (@mysql_close ($this->_dbhandle)! = 0)             {return 1;             } else {return 0; }}/** query all data table contents **/function SelectAll () {$query = ' select * from '. $this->_table. '            `';        return $this->query ($query); The/** query data table specifies the column contents **/function Select ($id) {$query = ' select * from '. $this->_table. ' ' WheRe ' id ' = \ '. mysql_real_escape_string ($id). '            \'';        return $this->query ($query, 1); }/** the custom SQL query statement **/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] = Trim (Ucfirst ($table [$i]), "s"); $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);        }}/** returns the number of result set rows **/function Getnumrows () {return mysql_num_rows ($this->_result);        }/** releases the result set memory **/function Freeresult () {mysql_free_result ($this->_result);       }/** returns the MySQL operation error message **/function GetError () {return mysql_error ($this->_dbhandle); }    }

Create a new model.class.php with the following code:

<?php    class Model extends sqlquery{        protected $_model;        function __construct () {            $this->connect (db_host,db_user,db_password,db_name);            $this->_model = Get_class ($this);            $this->_table = strtolower ($this->_model). " S ";        }        function __destruct () {        }    }

The new view EOG class is template.class.php and the code is as follows:

<?php class Template {protected $variables = array ();       protected $_controller;       protected $_action;           function __construct ($controller, $action) {$this->_controller = $controller;       $this->_action = $action;       }/* Set Variable */function set ($name, $value) {$this->variables[$name] = $value;           }/* Display template */function render () {Extract ($this->variables); if (File_exists (ROOT). Ds. ' Application '. Ds. ' Views '. Ds. $this->_controller. Ds. ' header.php ') {include (ROOT). Ds. ' Application '. Ds. ' Views '. Ds. $this->_controller. Ds.           ' header.php '); } else {include (ROOT. Ds. ' Application '. Ds. ' Views '. Ds.           ' header.php '); } include (ROOT. Ds. ' Application '. Ds. ' Views '. Ds. $this->_controller. Ds. $this->_action.           '. php '); if (File_exists (ROOT). Ds. ' Application '. Ds. ' Views '. Ds. $this->_controller. Ds. ' Footer.php ') {include (ROOT). Ds. ' Application '. Ds. ' Views '. Ds. $this->_controller. Ds.           ' footer.php '); } else {include (ROOT. Ds. ' Application '. Ds. ' Views '. Ds.           ' footer.php '); }        }    }

After doing so many operations, basically the entire MVC framework has come out, the following is the production of our site. The site we're going to do is actually very simple, a todo program.

The first is to create a new site Controller class Itemscontroller, named Itemscontroller.php, under our/application/controller/directory, with the following:

<?php class Itemscontroller extends Controller {function view ($id = null           , $name = null) {$this->set (' title ', $name. '-My Todo List App ');       $this->set (' Todo ', $this->item->select ($id));           } function Viewall () {$this->set (' title ', ' All items-my Todo List App ');       $this->set (' Todo ', $this->item->selectall ());           } function Add () {$todo = $_post[' Todo '];           $this->set (' title ', ' success-my Todo List App '); $this->set (' Todo ', $this->item->query (' INSERT into items (item_name) values (\ '. Mysql_real_escape_string ($ TODO). '       \')'));           } function Delete ($id) {$this->set (' title ', ' success-my Todo List App '); $this->set (' Todo ', $this->item->query (' Delete from items where id = \ '. mysql_real_escape_string ($id). '       \'')); }    }

The next step is to build a model of the site, in our/application/model/directory first built a site model class for item, the content directly inherit model, the code is as follows:

<?phpclass Item extends Model {}

The final step is to set up the view portion of our site, we now create a new items folder under the/application/views/directory, and then create the same file with the controller action under the Items folder. For view.php,viewall.php,add.php,delete.php, consider that this page may need to share the first page and footer, so create a new two files, named header.php,footer.php, each file code is as follows:

view.php file: View a single pending transaction


viewall.php file: View all pending transactions

<form action= ". /items/add "method=" POST ">    <input type=" text "value=" I have to ... "onclick=" this.value= "" Name= "Todo" > <input type= "Submit" value= "Add" ></form><br/><br/><?php $number = 0?><?php foreach ( $todo as $todoitem):?>    <a href= ". /items/view/<?php echo $todoitem [' Item '] [' ID ']?>/<?php echo strtolower (Str_replace ("", "-", $todoitem [' Item ' [' item_name '])?> ">        <span>            <?php echo + + $number?>            <?php echo $todoitem [' Item ' [' Item_name ']?>        </span>    </a><br/><?php endforeach?>

add.php files: Adding pending transactions

<a href= ". /items/viewall ">todo successfully added. Click here to go back.</a><br/>

delete.php Files: Deleting transactions

<a href= ". /.. /items/viewall ">todo successfully deleted. Click here to go back.</a><br/>

header.php: Top Page file


footer.php: End-of-page file

</body>

Of course, there is an essential operation is to create a table in the data, the code is as follows:

CREATE TABLE IF not EXISTS ' items ' (    ' id ' int (one) not null auto_increment,    ' item_name ' varchar (255) ' is not NULL,    PRIMARY KEY (' id ')) engine=myisam DEFAULT charset=latin1 auto_increment=17;

This is the development of a Web site using MVC, and you can now view the new site by visiting Http://localhost/todo/items/viewall.

  • Related Article

    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.