## 創建core/RouteCollection.php
````
<?php
namespace core;
use core\request\RequestInterface;
Class RouteCollection
{
protected $routes = []; // 所有路由存放
protected $route_index = 0; // 當前訪問的路由
public function getRoutes() // 獲取所有路由
{
return $this->routes;
}
public $currGroup = []; // 當前組
public function group($attributes = [],\Closure $callback)
{
$this->currGroup[] = $attributes;
call_user_func($callback,$this);
// $callback($this); 跟這個一樣的效果
// group的實現主要的這個$this 這個$this將當前狀態傳遞到了閉包
array_pop($this->currGroup);
}
// 增加/ 如: GETUSER 改成 GET/USER
protected function addSlash(& $uri)
{
return $uri[0] == '/' ? : $uri = '/'.$uri;
}
// 增加路由
public function addRoute($method,$uri,$uses)
{
$prefix = ''; // 前綴
$middleware = []; // 中間件
$namespace = ''; // 命名空間
$this->addSlash($uri);
foreach ($this->currGroup as $group){
$prefix .= $group['prefix'] ?? false;
if( $prefix) // 如果有前綴
$this->addSlash($prefix);
$middleware = $group['middleware'] ?? []; // 合并組中間件
$namespace .= $group['namespace'] ?? ''; // 拼接組的命名空間
}
$method = strtoupper($method); // 請求方式 轉大寫
$uri = $prefix .$uri;
$this->route_index = $method . $uri; // 路由索引
$this->routes[$this->route_index] = [ // 路由存儲結構 用 GET/USER 這種方式做索引 一次性就找到了
'method' => $method, // 請求類型
'uri' => $uri, // 請求url
'action' => [
'uses' => $uses,
'middleware' => $middleware,
'namespace' => $namespace
]
];
}
public function get($uri,$uses)
{
$this->addRoute('get',$uri,$uses);
return $this;
}
public function post($uri,$uses)
{
$this->addRoute('post',$uri,$uses);
return $this;
}
public function put($uri,$uess){} // 略寫 ...
public function delete($uri,$uses){}
public function middleware($class)
{
$this->routes[$this->route_index]['action']['middleware'][] = $class;
return $this;
}
// 獲取當前訪問的路由
public function getCurrRoute()
{
$routes = $this->getRoutes();
$route_index = $this->route_index;
if( isset( $routes[ $route_index]))
return $routes[ $route_index];
$route_index .= '/';
if( isset( $routes[ $route_index]))
return $routes[ $route_index];
return false;
}
// 更具request執行路由
public function dispatch(RequestInterface $request)
{
$method = $request->getMethod();
$uri = $request->getUri();
$this->route_index = $method . $uri;
$route = $this->getCurrRoute();
if(! $route) // 找不到路由
return 404;
$routerDispatch = $route['action']['uses'];
return $routerDispatch();
}
}
````
## 綁定路由
編輯 `app.php`

## 加載路由文件
編輯 `app.php` 的 `boot`方法
```
App::getContainer()->get('router')->group([
'namespace' => 'App\\controller'
], function ($router){
require_once FRAME_BASE_PATH . '/routes/web.php'; // 因為是require 所以web.php有$router這個變量
});
App::getContainer()->get('router')->group([
'namespace' => 'App\\controller',
'prefix' => 'api'
], function ($router){
require_once FRAME_BASE_PATH . '/routes/api.php';
});
```

## 創建routes/web.php和routes/api.php
編輯 `routes/web.php`:

## 編輯index.php

```
App::getContainer()->get('response')->setContent(
App::getContainer()->get('router')->dispatch(
App::getContainer()->get(\core\request\RequestInterface::class)
)
)->send();
```
## 運行

- 前言
- 基礎篇
- 1. 第一步 創建框架目錄結構
- 2. 引入composer自動加載
- 3. php自動加載 (解釋篇)
- 4. 創建容器 注冊樹模式
- 5. 關于psr規范解釋
- 6. 關于"容器" "契約" "依賴注入" (解釋篇)
- 7. 添加函數文件helpers.php
- 8. 初始化請求(Request)
- 9. 響應 (Response)
- 10. 路由一 (路由組實現)
- 11. 路由二 (加入中間件)
- 12. 配置信息 (類似laravel)
- 13. 數據庫連接 (多例模式)
- 14. 查詢構造器 (query builder)
- MVC實現
- M 模型實現 (數據映射 + 原型 模式)
- C 控制器實現 + 控制器中間件
- V 視圖實現 (Laravel Blade 引擎)
- V 視圖切換成 ThinkPhp 模板 引擎)
- 其他輪子
- 日志
- 自定義異常 (異常托管)
- 單元測試 (phpunit)
- 替換成swoole的http服務器
- 協程上下文解決request問題
- qps測試
- 發布到packagist.org