3.1 路由 漂亮的URL絕對是一個嚴肅的web應用程式必須做到的,這種方式使index.php?article_id=57這類的醜陋URL被隱藏,由更受歡迎的像 /read/intro-to-symfony 來替代。 3.1.1 路由配置 配置文件為app/Config/routes.php 以上 ...
漂亮的URL絕對是一個嚴肅的web應用程式必須做到的,這種方式使index.php?article_id=57這類的醜陋URL被隱藏,由更受歡迎的像 /read/intro-to-symfony 來替代。
配置文件為app/Config/routes.php
<?php return [ '/demo/{productName}' => [ 'name' => 'test1', 'controller' => 'App\Modules\Demo\Controller\FooController', 'action' => 'bar', 'required' => ['productName' => '\w+'], ], ];
以上邊代碼為例詳述一下如何配置一個優雅(laravel病上身...)的路由
'/demo/{productName}'是路由的匹配規則,其中配置中的required制定的就是productName必須滿足的正則條件,在框架的實際運行過程中會將路由規則+required解析為正則表達式/demo/(\w+) ,當url(eg: xxx.xxx.xxx/demo/testproduct)匹配到這條正則時就會執行配置中的controller的action,具體的執行為:FooController->bar($productName);
可以看到路由規則中的大括弧的內容(productName)就是就是bar這個方法的參數。所以在匹配路由時一定要註意路由規則必須與具體的控制器的方法的參數個數是一致的,不然就會拋出ControllerException。
如果我們每定義一個Controller就要配置一個路由就會導致開發效率較低,為了防止這種問題發生Minor提供了預設路由機制。當我們訪問http://xxx.xxx.xxx/demo/foo/bar時就會執行App\Modules\Demo\FooController的bar方法,即預設路由為:
http://xxx.xxx.xxx/{模塊名}/{控制器名}/{方法名}
正如你所見,Minor的路由並不強大。不支持請求方法的限制,不支持htttps限制,不支持過濾器。
Controller的定義非常簡單,只要繼承Minor\Controller\Controller基礎類就可以了(當然你也可以不繼承,但是基類中的方法和屬性就不能使用了,這很好理解),首先創建文件夾app/Modules/Demo/Controller/,然後再創建文件FooController.php:
<?php namespace App\Modules\Demo\Controller; use Minor\Controller\Controller; // 定義一個控制器 class FooController extends Controller { // 定義一個方法 public function bar() { return 'Hello World'; } }
通過訪問xxx.xxx.xxx/demo/foo/bar(預設路由,你也可以配置自己的路由)就可看到返回了Hello World。
調用Url的gen方法可以將預設路徑轉為符合路由規則的url
$url = Url:gen($path);
如根據3.1.1中的路由配置Url::gen('/demo/foo/bar?productName=test') 將返回 /demo/test。
Minor提供了三個跳轉的方法分別是redirect、forward、forwardUrl(這三個都是Minor\Controller\Controller的protected方法)。
當跳轉到另外一個url時可以在控制器這樣調用:$this->redirect($url);
當轉向(froward)到另外一個url時可以在控制器中這樣調用: $this->forwardUrl($url);(該方法的實現其實就是通過路由解析出url請求的控制器和方法然後調用forward($controller, $action, $param))
當轉向(forward)到另外一個方法時可以在控制器中這樣調用: $this->forward($controller, $action, $params); (參數$controller是控制器的類名,包含命名空間)
例:
class FooController extends Controller { public function bar() { $this->redirect('www.baidu.com'); return $this->forward('App\Modules\Demo\Controller\FooController', 'bar', 'test'); return $this->forward('/demo/testpro'); } }
調用MinorRequest的get($paramName, $defaultParamValue = null) 或者 post($paramName, $defaultParamValue = null)方法就可以獲取請求方法,在控制器中可以這樣調用:
class FooController extends Controller { public function bar() { $minorRequest = $this->app->getMinorRequest();
$paramValue = $minorRequest->get('paramKey', 'defaultValue');
... } }
調用MinorRequest的getMethod()方法就可以獲取請求的方法:
class FooController extends Controller { public function bar() { $minorRequest = $this->app->getMinorRequest(); $method = $minorRequest->getMethod(); ... } }
Minor提供了一個極其強大的模板引擎,這個模板引擎的名稱就是: PHP。是的!你沒看錯就是PHP。為什麼Minor不提供一個類似於smarty或者Twig這樣的模板引擎呢? 因為沒有必要,PHP本身已經足夠好了,如果Minor再造一個模板引擎無疑就會使Minor更難上手,所以Minor直接使用PHP作為視圖文件的語言。
在控制器中使用視圖只需要調用View::render('模塊名:控制器名:視圖文件名', ['param1key' => 'param1value', 'param2key' => 'param2value' ...]);例:
class FooController extends Controller { public function bar() { $param1 = 'Hello'; $param2 = 'World'; return View::render('Demo:Foo:bar.php', ['param1' => $param1, 'param2' => $param2]); } }
render函數的第二個參數(['param1key' => 'param1value', 'param2key' => 'param2value' ...])就是向視圖文件中傳遞的變數,我們可以在視圖文件中使用這些變數:
文件:app/Modules/Demo/Controller/Tpl/Foo/bar.php
<?php echo $param1key;?>
<?=$param2key ?>
Minor提供了兩個視圖文件中可以使用的函數:
function include_tpl($module, $controller, $tpl) { require_once (!defined('APP_DIR') ? APP_DIR : realpath(__DIR__ . '/../../app/') .DIRECTORY_SEPARATOR) . 'Modules' . '/' . $module . '/Tpl/' . $controller . '/' . $tpl; } function url($path) { return Url::gen($path); }
使用:
html> <?php include_tpl('Public', 'Public', 'header.php');?> <body> <h1>Hello!</h1> <a href="<?php url('/demo/foo/bar?productName=testpro');?>"> </body> </html>
這兩個函數定義在app/Resource/functions.php文件中,你可以在這個文件中自定義你需要的視圖函數。
可以在控制器中通過調用App對象的getMinorResponse()方法來獲取當前MinorResponse對象。 MinorResponse類提供了六個方法分別是:
public function send(); // 用於將響應對象發送給客戶端
public function setHeader($header);// 設置響應頭
public function setContent($content); // 設置響應對象的內容
public function beforeContent($content); // 在當前已有的內容之前添加內容
public function appendContent($content); // 在當前已有內容之後追加內容
public function getContent(); // 獲取對象中的響應內容