# 路由與控制器
## 路由
Blink 默認的路由配置位于?`src/http/routes.php`?文件中,該文件返回一個數組,包含應用所有的路由定義。 下面是一個簡單的路由配置文件:
~~~
<?php
return [
['GET', '/', function () {
return 'hello world';
}],
['GET', '/foo/bar', function () {
return 'hello foo bar';
}]
];
~~~
路由的定義也支持指定多個 HTTP 請求方法(HTTP Method),實例如下:
~~~
return [
[['GET', 'HEAD'], '/', function () {
// 該路徑下的 GET 和 HEAD 請求都將由該函數處理
return 'hello world';
}]
];
~~~
## 帶參數的路由
路由的定義也可以攜帶參數,我們使用`{param}`?的語法來定義一個參數,其中`param`是參數的名稱,控制器函數需要按順序接受 框架傳遞過來的參數。如下的例子中定義了 type 和 id 兩個參數:
~~~
return [
['GET', '/users/{type}/{id}', function ($type, $id) {
// 路由中定義的參數可以直接在控制器函數或方法中獲取
}]
];
~~~
上面的例子沒有對 type 和 id 參數做任何限制,實際上下面這些 URL 都能通過該路由的校驗:
~~~
/users/foo/123
/users/321/bar
/users/foo/bar
~~~
但實際上我們可以只希望?`/users/foo/123`?通過檢驗,這時我們可以使用正則表達式限制每個參數的值,其對應的語法是`{param:expression}`, 下面的路由定義就符合我們的預期:
~~~
return [
['GET', '/users/{type:[a-zA-Z]+}/{id:\d+}', function ($type, $id) {
// 現在的 type 就限定為字符串, id 限定為整數了
}]
];
~~~
## 控制器
控制器函數除了上文中使用的匿名函數,更常見的是使用類的方法。我們使用?`ClassName@method`?這樣的語法指定類方法作為控制器函數,如:
~~~
return [
['GET', '/', '/app/http/controllers/IndexController@index']
];
~~~
該示例中我們采用了類的絕對命名空間,這個看起來會比較繁瑣,這是我們可以結合?`src/config/app.php`?中的`controllerNamespace`?配置,采用相對的命名空間格式,簡化代碼。結合兩者,下面示例達到的效果將完全一致:
src/config/app.php
~~~
return [
'controllerNamespace' => '\app\http\controllers',
];
~~~
src/http/routes.php
~~~
return [
['GET', '/', 'IndexController@index']
];
~~~
## 依賴注入
Blink 支持控制器的構造函數和普通方法兩種注入方式。通過依賴注入,我們可以很方便的把需要的對象拿來使用,而不用關心這些對象是怎么創建的, 框架本身自然會很好的處理好對象的創建。下面是一個簡單的控制器注入案例:
~~~
use blink\core\Object;
use blink\http\Request;
class Controller extends Object
{
/**
* 這里通過構造函數注入 Request 對象
*/
public function __construct(Request $request, $config = [])
{
parent::__construct();
}
/**
* 這里在普通方法中注 Request 對象
*
* @param $id 路由參數 id 的值,注意路由參數需要放在參數列表的前面
* @param $request 注入的 Request 對象
*/
public function index($id, Request $request)
{
}
}
~~~