視圖裝載類要作的工做其實很簡單:php
1. 根據視圖名稱找到視圖文件,支持文件夾html
2. 更加方便,更加優雅地把變量的值傳遞進視圖前端
本文中咱們將不會不引入模板引擎,只作裝載文件和傳遞變量的功能。git
咱們要引入視圖裝載器,這就正式打開了組件化的大門,因此咱們須要作一些準備工做。github
將 public/index.php 裏面的代碼分離一部分到啓動器(bootstrap),新建 MFFC/bootstrap.php 文件:json
<?php use Illuminate\Database\Capsule\Manager as Capsule; // 定義 BASE_PATH define('BASE_PATH', __DIR__); // Autoload 自動載入 require BASE_PATH.'/vendor/autoload.php'; // Eloquent ORM $capsule = new Capsule; $capsule->addConnection(require BASE_PATH.'/config/database.php'); $capsule->bootEloquent();
修改 public/index.php 爲:bootstrap
<?php // 定義 PUBLIC_PATH define('PUBLIC_PATH', __DIR__); // 啓動器 require PUBLIC_PATH.'/../bootstrap.php'; // 路由配置、開始處理 require BASE_PATH.'/config/routes.php';
這時候咱們就完成了 入口文件 和 啓動器 的分離,並定義了兩個全局常量 BASE_PATH 和 PUBLIC_PATH 。後端
在這裏咱們須要特別注意一點:「引入路由配置文件」 這一步並不僅是簡單地引入了一個配置文件,路由文件的最後一行 Macaw::dispatch(); 纔是 真正執行某個控制器中某個 function 的地方,全部準備條件都應該在載入路由文件以前完成,例如 Eloquent 的初始化,還有之後咱們要使用的 Composer 包的初始化等等。瀏覽器
咱們選擇 filp/whoops 做爲咱們錯誤提示組件包。app
修改 composer.json :
"require": { "codingbean/macaw": "dev-master", "illuminate/database": "*", "filp/whoops": "*" }
運行 composer update ,而後將 bootstrap.php 修改成以下:
<?php use Illuminate\Database\Capsule\Manager as Capsule; // 定義 BASE_PATH define('BASE_PATH', __DIR__); // Autoload 自動載入 require BASE_PATH . '/vendor/autoload.php'; // Eloquent ORM $capsule = new Capsule; $capsule->addConnection(require BASE_PATH . '/config/database.php'); $capsule->bootEloquent(); // whoops 錯誤提示 $whoops = new \Whoops\Run; $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler); $whoops->register();
下面咱們將增長路由配置中 無匹配項 的錯誤頁面,修改 config/routes.php :
<?php use NoahBuscher\Macaw\Macaw as Route; Route::get('/', function() { echo "Welcome"; }); Route::get('/name/(:all)', function($name) { echo 'Your name is '.$name; }); Route::get('home', 'HomeController@home'); Route::error(function() { throw new Exception("404 Not Found"); }); Route::dispatch();
如今訪問一個隨意輸入的 URL ,咱們會看到如下畫面:
是否是有一種很高大上的感受!(連報錯都這麼優雅⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄)
完成基礎準備之後咱們正式開始製造視圖裝載器。
視圖裝載器是一個可插拔組件,咱們應該把全部可插拔組件所有歸到一處,在 MFFC 中建議放在 MFFC/services 下。
咱們並無像 CI 框架那樣把視圖裝載器放到系統核心,有如下兩個緣由:
下面開始着手實現視圖裝載器。
新建 MFFC/services 文件夾,並修改 composer.json 把這個文件夾下的全部類自動納入根命名空間:
{ "require": { "noahbuscher/macaw": "dev-master", "illuminate/database": "*", "filp/whoops": "*" }, "autoload": { "classmap": [ "app/controllers", "app/models", "app/class", "services" ] } }
新建 services/View.php 文件,內容以下:
<?php /** * ViewLoad */ class View { const VIEW_BASE_PATH = '/app/views/'; public $view; public $data; /** * View constructor. * @param $view */ public function __construct($view) { $this->view = $view; } /** * 建立視圖 * @param null $viewName * @return View */ public static function make($viewName = null) { if ( ! $viewName ) { throw new InvalidArgumentException("視圖名稱不能爲空!"); } else { $viewFilePath = self::getFilePath($viewName); if ( is_file($viewFilePath) ) { return new View($viewFilePath); } else { throw new UnexpectedValueException("視圖文件不存在!"); } } } /** * 變量傳遞 * @param $key * @param null $value * @return $this */ public function with($key, $value = null) { $this->data[$key] = $value; return $this; } /** * 視圖路徑 * @param $viewName * @return string */ private static function getFilePath($viewName) { $filePath = str_replace('.', '/', $viewName); return BASE_PATH.self::VIEW_BASE_PATH.$filePath.'.php'; } /** * @param $method * @param $parameters * @return View */ public function __call($method, $parameters) { if (starts_with($method, 'with')) { return $this->with(snake_case(substr($method, 4)), $parameters[0]); } throw new BadMethodCallException("方法 [$method] 不存在!."); } /** * 傳輸視圖及變量 */ public function __destruct() { if ($this->data) extract($this->data); require $this->view; } }
運行 composer dump-autoload ,完成之後,咱們就能夠在控制器中直接調用這個類了。
修改 controllers/HomeController.php :
<?php class HomeController extends BaseController { public function home() { return View::make('home') ->with('article', Articles::find(1)) ->withTitle('Frame') ->withShowMsg('hello world'); } }
修改 app/views/home.php :
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title><?php echo $title ?></title> </head> <body> <div class="article"> <h1><?php echo $article['name'] ?></h1> <div class="content"> <?php echo $article ?> </div> </div> <ul class="msg"> <h1><?php echo $show_msg ?></h1> </ul> </body> </html>
刷新,你將看到如下頁面: