運用composer實現一個簡陋的MVC架構

背景原因

網上有許多本身去編寫一些類來實現MVC框架的有不少。這個是在我進行項目改造的過程當中操做的手法,搭建一個簡陋的MVC的簡易架構其中model和view是使用的laravel中的。下列實現的方式在不少地方會跟laravel很類似哦,廢話很少說,直接上步驟。(這裏假設你已經按照了composer)php

Step1 Composer init

直接執行composer init,按照步驟一步步下去,建立composer.json文件
圖片描述html

使用composer能夠實現類的自動加載功能,運用該功能是用來額,怎麼說呢,偷懶的。將生成的composer文件按下圖修改,而後按下圖左邊目錄結構建立。
圖片描述mysql

修改完配置後執行laravel

composer install
composer dump-autoload

Step 2 構建一些基本文件及功能

以後在helper.php文件中添加一個函數,該函數是判斷函數及其controller存在與否git

if (!function_exists('isAvailableController')) {

    function isAvailableController($controller,$method,$debug)
    {
        if(class_exists($controller)){
            $app =$controller::getinstance();
            //判斷調用的方法控制器類中是否存在
            if(!method_exists($controller,$method)){
                echo $controller.'類不存在'.$method.'方法!';
                die();
            }
        } else {
            echo $controller.'類不存在!';
            die();
        }
        return $app;
    }
}

Controllers目錄下新建一個Controller做爲抽象類github

<?php

/**
 * Created by PhpStorm.
 * User: Damon
 * Date: 2017/12/26
 * Time: 2017/12/26
 * Info: basic controller
 */

namespace App\Controllers;

abstract class Controller
{

    protected static $instance = null;
    final protected function __construct(){
        $this->init();
    }

    final protected function __clone(){}
    protected function init(){}
    //abstract protected function init();

    public static function getInstance(){
        if(static::$instance === null){
            static::$instance = new static();
        }
        return static::$instance;
    }

}

以後在Controllers目錄下新建控制器就好了,例如我實現一個TestController請注意新建的控制器必須以Controller結尾並繼承上面的Controller,以下:sql

namespace App\Controllers;


class TestController extends Controller
{
    public function index()
    {
        echo 'link start ^_^';
    }
}

建立一個配置文件config.php數據庫

return [
    'DEBUG' => true,
    'timeZone' => 'Asia/Shanghai',
    'APP_ROOT' => dirname(__FILE__),
    'VIEW_ROOT' => dirname(__FILE__).'/app/View',

];

以後呢,在項目根目錄(這裏就是mvc目錄)下創建一個index.phpjson

<?php
/**
 * Created by PhpStorm.
 * User: Damon
 * Date: 2017/12/27
 * Time: 15:37
 */
$config = require('./config.php');
define('APP_ROOT',$config['APP_ROOT']);//設定項目路徑
define('VIEW_ROOT',$config['VIEW_ROOT']);//設定視圖路徑
//composer自動加載
require __DIR__ . '/vendor/autoload.php';
date_default_timezone_set($config['timeZone']);//時區設定
//獲取控制器名稱
if (empty($_GET["c"])) {
    $controller = '\App\\Controllers\\BaseController';
} else {
    $controller = '\App\\Controllers\\' . $_GET["c"] . 'Controller';
}

$method = empty($_GET["m"]) ? 'index' : $_GET["m"];//獲取方法名
$app = isAvailableController($controller, $method, $config['DEBUG']);//實例化controller
echo $app->$method();
die();

從上面的代碼上其是能夠看到若是沒有傳遞get參數爲c的會自動調用BaseController,該控制器繼承自抽象類Controller,裏面有個index方法,這裏直接return一個字符串link start ^_^ 。那基本上以後要調用某個控制器的某個方法就是用url來實現例如http://localhost/mvc/?c=Test&... 就是調用TestController控制器下的index方法。如今來看下是否內實現:
圖片描述架構

看來沒有問題,其餘比較深奧的什麼路由重寫啊神馬的,先不考慮。

Step3 實現模板引擎

這裏實現模板引擎的方式是使用laravel的blade模板引擎,如何引入呢,這裏使用composer來引入一個包來解決。

composer require xiaoler/blade

這個包git上有比較詳細的說明,這個是xiaoler/blade包的鏈接

引入完這個包怎麼實現模板引擎呢,我本身是根據包的說明實現了一個View類把他放到Cores目錄下內容以下:

namespace App\Cores;
use Xiaoler\Blade\FileViewFinder;
use Xiaoler\Blade\Factory;
use Xiaoler\Blade\Compilers\BladeCompiler;
use Xiaoler\Blade\Engines\CompilerEngine;
use Xiaoler\Blade\Filesystem;
use Xiaoler\Blade\Engines\EngineResolver;
class View
{
    const VIEW_PATH = [APP_ROOT.'/app/View'];
    const CACHE_PATH = APP_ROOT.'/storage/framework/cache';

    public static function getView(){
        $file = new Filesystem;
        $compiler = new BladeCompiler($file, self::CACHE_PATH);
        $resolver = new EngineResolver;
        $resolver->register('blade', function () use ($compiler) {
            return new CompilerEngine($compiler);
        });
        $factory = new Factory($resolver, new FileViewFinder($file, self::VIEW_PATH));

        return $factory;
    }
}

測試一下,http://localhost/mvc/?c=Test&...,也就是調用TestController的index方法
圖片描述

該控制器的代碼以下:

namespace App\Controllers;


use App\Cores\View;

class TestController extends Controller
{
    public function index()
    {
        $str = '模板在哪裏啊,模板在這裏。';
        return View::getView()->make('index', ['str' => $str])->render();
    }
}

控制器中調用的模板是index.blade.php,內容以下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>home view</title>
</head>
<body>
{{ $str }}
</body>
</html>

模板引擎功能OK啦,以後就能夠愉快地使用blade模板引擎了,不過有些laravel中自帶的一些語法是不能用的哦,該包的git上有說明這裏引用下

  • @inject @can @cannot @lang 關鍵字被移除了
  • 不支持事件和中間件

Step4 實現Model

這裏使用的是illuminate / database包來實現Model的,執行如下命令安裝。

composer require illuminate/database

Core目錄下新建一個DB類,代碼以下:

<?php
/**
 * Created by PhpStorm.
 * User: Damon
 * Date: 2017/12/28
 * Time: 9:13
 */

namespace App\Cores;
use Illuminate\Database\Capsule\Manager as Capsule;

class DB
{

    protected static $instance = null;
    final protected function __construct(){
        $this->init();
    }

    final protected function __clone(){}
    protected function init(){
        $capsule = new Capsule;
        $capsule->addConnection([
            'driver' => 'mysql',
            'host' => 'localhost',
            'database' => 'mes',
            'username' => 'root',
            'password' => '12345678',
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
        ]);

        // Make this Capsule instance available globally via static methods... (optional)
        $capsule->setAsGlobal();

        // Setup the Eloquent ORM... (optional; unless you've used setEventDispatcher())
        $capsule->bootEloquent();
    }
    //abstract protected function init();

    public static function linkStart(){
        if(static::$instance === null){
            static::$instance = new static();
        }
        return static::$instance;
    }
}

這樣在controller中就可使用了,例如先在app目錄下創建Model目錄,在Model中新建一個Model文件Matter.php。

<?php
/**
 * Created by PhpStorm.
 * User: Damon
 * Date: 2017/12/28
 * Time: 9:52
 */

namespace App\Model;

use Illuminate\Database\Eloquent\Model;

class Metal extends Model
{
    protected $fillable = ['metal_code','metal_name','metal_type','enable','deadline'];
    protected $table = 'mes_metal';
    public $timestamps = false;
}

以後能夠在控制器中這麼使用:

<?php
/**
 * Created by PhpStorm.
 * User: Damon
 * Date: 2017/12/27
 * Time: 16:08
 */

namespace App\Controllers;

use App\Cores\DB;
use App\Cores\View;
use App\Model\Metal;

class TestController extends Controller
{
    public function index()
    {
        DB::linkStart();//鏈接db
        Metal::create([
            'metal_code' => 'TEST',
            'metal_name' => 'test',
            'materiel_type' => 1,
            'enable' => 0,
            'deadline' => 30
        ]);
        $res= Metal::all()->toArray();

        var_dump($res);
        die();
        
    }
}

這裏有一些限制,就是沒法使用laravel中的DB::connect(),不過其餘的基礎使用好像均可以。而且這裏沒法切換鏈接的數據庫,這個其實能夠將DB類進行修改,至於如何修改,本身想嘍。這個project放到了github上,點擊這裏查看。

相關文章
相關標籤/搜索