PHP implements a simple MVC framework

1, Foreword

The full name of MVC is Model View Controller. It is a mode of using Model View Controller to design and create web applications. It is a design model.

Of which:

  • Model: it is the part of the application used to process the application data logic. It is usually responsible for curd interaction directly with the database.

  • View: it is the part of the application that processes the data display by rendering the processed data.

  • Controller: it is the part of an application that handles user interaction. It is usually used to handle the distribution of data logic and send it back to the view and controller accordingly.

advantage:

  • Low coupling
  • High reusability
  • Fast deployment and low life cycle cost
  • High maintainability

Disadvantages:

  • It increases the complexity of system structure and implementation
  • Too tight connection between view and controller

2, Which frameworks use mvc architecture?

At present, mvc architecture has been used in the mainstream frameworks of php, such as:

thinkPHP, Laravel and Yii all have mvc architecture.

3, Introduction to frame structure


Of which:

  • app Directory: used to store view controller models, etc.
  • config Directory: used to store some public configuration files of the framework.
  • core Directory: used to store some base class files, such as controller base class, model base class, view base class, request request base class, db chain operation base class, etc.
  • Static Directory: used to store some static resources, such as pictures, html view files, js, cs files, etc.
  • index.php: the entry file of the whole framework for distribution and startup.

4, The first step of framework implementation (resolving routing)

Why is resolving routing the first step?

MVC can only be used after successfully resolving the route and accessing a method in a class, because resolving the route is also the most basic part of the framework implementation, and the automatic loading mechanism of PHP is indispensable for resolving the route

At present, the automatic loading mechanism of php can be divided into two mechanisms: composer automatic loading mechanism and manual automatic loading mechanism. This simple framework is completed by manual automatic mechanism.

4.1 write entry file

index.php:

<?php
//Define application directory
const APP_PATH = __DIR__ . '/';

//Load framework core file
require(APP_PATH . 'core/Core.php');

//Instantiate the framework class and run it
(new core\Core())->run();

Code details:

In the first step, constants are defined to define the application directory, which may be used somewhere later.
The second step is to load the framework core file Core.php, and the main core logic is also concentrated in this file.
Step 3: instantiate the class and call the run method of the class.

4.2 defining Core classes

Core.php:

<?php
namespace core;

class Core
{
    public function run()
    {
        spl_autoload_register(array($this, 'loadClass'));
        $this->route();
    }

    public function route()
    {
        $url = $_SERVER['REQUEST_URI'];
        $position = strpos($url, '?');
        $url = $position === false ? $url : substr($url, 0, $position);
        $url = trim($url, '/');
        if ($url)
        {
            //Specify controller by URL
            $urlArray = explode('/', $url);
            $controllerName = ucfirst($urlArray[count($urlArray)-2]);
            $actionName = $urlArray[1];
        }else{
            //Go to default controller
            $controllerName = 'Index';
            $actionName = 'index';
        }
        $versionUrlArr = explode('/',$url);
        $versionUrlArr = array_slice($versionUrlArr,0,-2);
        $versionStr = implode('\\',$versionUrlArr);
        if (empty($versionStr)){
            $versionStr = $versionStr;
        }else{
            $versionStr = $versionStr.'\\';
        }
        $controller = 'app\\controllers\\'.$versionStr. $controllerName . 'Controller';
        if (!class_exists($controller)) {
            exit($controller . 'Controller does not exist');
        }
        if (!method_exists($controller, $actionName)) {
            exit($actionName . 'Method does not exist');
        }
        $dispatch = new $controller($controllerName, $actionName);
        $dispatch->$actionName();
    }
    
    public function loadClass($className)
    {
        $className = str_replace('\\','/', $className);
        $file = $className . '.php';
        if (file_exists($file)){
            require_once $file;
        }
    }
}

First, the run method of this class is called. The run method is mainly responsible for invoking some methods needed to invoke the runtime framework. First, it registers the automatic loading method loadClass, and then calls the analytical routing method (here is the key point. Here, the input interface address of the address bar is directly accessible to the controller).

be careful ⚠️: The resolution rules of routing are defined by ourselves.

Code details:

Step 1: register the auto loading class for route resolution and namespace use.
Step 2: call the route resolution method, resolve the domain name / controller name / method name entered in the address bar, and call it.

After a series of parsing, the new class name and the method name are finally called to realize the successful parsing of the route, so as to access a method under a class.

$dispatch = new $controller($controllerName, $actionName);
$dispatch->$actionName();

For example, to access the demo method under the app\controllers\StudentController.php file:

<?php
namespace app\controllers;

use core\base\Controller;

class StudentController extends Controller
{
    public function demo()
    {
        echo 'The bald head that writes code is strong';
    }
}

5, The second step of framework implementation (MVC Implementation)

Through the first step, you have completed the address bar and entered the path to access a controller. Next, you need to perform MVC operation in the controller.

5.1 realization of controller

The controller itself has been implemented, but we need to inherit a controller base class to implement some operations, such as registering some global exception classes, registering some request classes, mutual calls between controllers, etc.

5.2 realization of view

The view base class file is written to the core/base/View.php file:

<?php
namespace core\base;

/**
 * View base class
 */
class View
{
    protected $variables = array();
    protected $_controller;
    protected $_action;

    function __construct($controller, $action)
    {
        $this->_controller = strtolower($controller);
        $this->_action = strtolower($action);
    }

    public function assign($name, $value)
    {
        $this->variables[$name] = $value;
    }

    public function render()
    {
        try {
            extract($this->variables);
            $file = APP_PATH . 'app/views/' . $this->_controller . '/' . $this->_action . '.php';
            if (file_exists($file)){
                require_once $file;
            }else{
                require_once APP_PATH.'core/errorpage/404.html';
            }
        }catch (\Exception $e){
            echo $e->getMessage();
        }

    }
}

Code details:

Among them, the view function has two major functions.

The first function: assign.

We usually pass values through

$this->assign('name','The bald head that writes code is strong');
$this->assign('sex','male');

This method is used to transfer values.

The methods implemented in the framework are:

public function assign($name, $value)
{
   $this->variables[$name] = $value;
}

It is obvious that all key value pairs are placed in an array.

The second function: View mapping (render)

Implementation code:

public function render()
{
   extract($this->variables);
   $file = APP_PATH . 'app/views/' . $this->_controller . '/' . $this->_action . '.php';
   if (file_exists($file)){
       require_once $file;
   }else{
       require_once APP_PATH.'core/errorpage/404.html';
   }
}

After receiving the controller name and method name, splice them to the address of the custom view resolution rule and import them directly.

5.3 model implementation

The soul of implementing the model is to use the controller name as the table name.

In the controller:

$data = ['name' => 'tom'];
$model = new StudentModel();
$model->addData($data);

In a custom model:

<?php
namespace app\models;

use core\base\Model;
class StudentModel extends Model
{
    protected $table = 'student';

    public function addData($data)
    {
        $this->add($data);
    }
}

Model base class:

<?php
namespace core\base;

use core\db\Orm;

class Model extends Orm
{
    protected $table;
    public function __construct()
    {
        echo $this->table;
    }

    public function add($data){
        //Process add logic
    }
}

In the model base class, we can customize orm to complete the interaction with the database.

6, Summary

The above only introduces the simplest MVC implementation case. There is no fixed implementation method to implement the MVC framework. It can be implemented according to the characteristics of the framework, language characteristics and their own needs.

Keywords: PHP

Added by thetick on Wed, 01 Dec 2021 01:36:54 +0200