* Add translate docs action * Remove push Co-authored-by: sy-records <sy-records@users.noreply.github.com>
9.3 KiB
路由
預設情況下路由由 nikic/fast-route 提供支援,並由 hyperf/http-server 元件負責接入到 Hyperf
中,RPC
路由由對應的 hyperf/rpc-server 元件負責。
HTTP 路由
通過配置檔案定義路由
在 hyperf-skeleton 骨架下,預設在 config/routes.php
檔案內完成所有的路由定義,當然如果您路由眾多,您也可以對該檔案進行擴充套件,以適應您的需求,但 Hyperf
還支援 註解路由
,我們更推薦使用 註解路由
,特別是在路由眾多的情況下。
通過閉包定義路由
構建一個最基本的路由只需一個 URI 和一個 閉包(Closure)
,我們直接通過程式碼來演示一下:
<?php
use Hyperf\HttpServer\Router\Router;
Router::get('/hello-hyperf', function () {
return 'Hello Hyperf.';
});
您可以通過 瀏覽器 或 cURL
命令列來請求 http://host:port/hello-hyperf
來訪問該路由。
定義標準路由
所謂標準路由指的是由 控制器(Controller)
和 操作(Action)
來處理的路由,如果您使用 請求處理器(Request Handler)
模式也是類似的,我們通過程式碼來演示一下:
<?php
use Hyperf\HttpServer\Router\Router;
// 下面三種方式的任意一種都可以達到同樣的效果
Router::get('/hello-hyperf', 'App\Controller\IndexController::hello');
Router::get('/hello-hyperf', 'App\Controller\IndexController@hello');
Router::get('/hello-hyperf', [App\Controller\IndexController::class, 'hello']);
該路由定義為將 /hello-hyperf
路徑繫結到 App\Controller\IndexController
下的 hello
方法。
可用的路由方法
路由器提供了多種方法幫助您註冊任何的 HTTP 請求的路由:
use Hyperf\HttpServer\Router\Router;
// 註冊與方法名一致的 HTTP METHOD 的路由
Router::get($uri, $callback);
Router::post($uri, $callback);
Router::put($uri, $callback);
Router::patch($uri, $callback);
Router::delete($uri, $callback);
Router::head($uri, $callback);
// 註冊任意 HTTP METHOD 的路由
Router::addRoute($httpMethod, $uri, $callback);
有時候您可能需要註冊一個可以同時響應多種 HTTP METHOD 請求的路由,可以通過 addRoute
方法實現定義:
use Hyperf\HttpServer\Router\Router;
Router::addRoute(['GET', 'POST','PUT','DELETE'], $uri, $callback);
路由組的定義方式
實際路由為 group/route
, 即 /user/index
, /user/store
, /user/update
, /user/delete
Router::addGroup('/user/',function (){
Router::get('index','App\Controller\UserController@index');
Router::post('store','App\Controller\UserController@store');
Router::get('update','App\Controller\UserController@update');
Router::post('delete','App\Controller\UserController@delete');
});
通過註解定義路由
Hyperf
提供了非常便利的 註解 路由功能,您可以直接在任意類上通過定義 @Controller
或 @AutoController
註解來完成一個路由的定義。
@AutoController
註解
@AutoController
為絕大多數簡單的訪問場景提供路由繫結支援,使用 @AutoController
時則 Hyperf
會自動解析所在類的所有 public
方法並提供 GET
和 POST
兩種請求方式。
使用
@AutoController
註解時需use Hyperf\HttpServer\Annotation\AutoController;
名稱空間;
駝峰命名的控制器,會自動轉化為蛇形路由,以下為控制器與實際路由的對應關係示例:
控制器 | 註解 | 訪問路由 |
---|---|---|
MyDataController | @AutoController() | /my_data/index |
MydataController | @AutoController() | /mydata/index |
MyDataController | @AutoController(prefix="/data") | /data/index |
<?php
declare(strict_types=1);
namespace App\Controller;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Annotation\AutoController;
/**
* @AutoController()
*/
class UserController
{
// Hyperf 會自動為此方法生成一個 /user/index 的路由,允許通過 GET 或 POST 方式請求
public function index(RequestInterface $request)
{
// 從請求中獲得 id 引數
$id = $request->input('id', 1);
return (string)$id;
}
}
@Controller
註解
@Controller
為滿足更細緻的路由定義需求而存在,使用 @Controller
註解用於表明當前類為一個 Controller
類,同時需配合 @RequestMapping
註解來對請求方法和請求路徑進行更詳細的定義。
我們也提供了多種快速便捷的 Mapping
註解,如 @GetMapping
、@PostMapping
、@PutMapping
、@PatchMapping
、@DeleteMapping
5 種便捷的註解用於表明允許不同的請求方法。
使用
@Controller
註解時需use Hyperf\HttpServer\Annotation\Controller;
名稱空間;
使用@RequestMapping
註解時需use Hyperf\HttpServer\Annotation\RequestMapping;
名稱空間;
使用@GetMapping
註解時需use Hyperf\HttpServer\Annotation\GetMapping;
名稱空間;
使用@PostMapping
註解時需use Hyperf\HttpServer\Annotation\PostMapping;
名稱空間;
使用@PutMapping
註解時需use Hyperf\HttpServer\Annotation\PutMapping;
名稱空間;
使用@PatchMapping
註解時需use Hyperf\HttpServer\Annotation\PatchMapping;
名稱空間;
使用@DeleteMapping
註解時需use Hyperf\HttpServer\Annotation\DeleteMapping;
名稱空間;
<?php
declare(strict_types=1);
namespace App\Controller;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
/**
* @Controller()
*/
class UserController
{
// Hyperf 會自動為此方法生成一個 /user/index 的路由,允許通過 GET 或 POST 方式請求
/**
* @RequestMapping(path="index", methods="get,post")
*/
public function index(RequestInterface $request)
{
// 從請求中獲得 id 引數
$id = $request->input('id', 1);
return (string)$id;
}
}
註解引數
@Controller
和 @AutoController
都提供了 prefix
和 server
兩個引數。
prefix
表示該 Controller
下的所有方法路由的字首,預設為類名的小寫,如 UserController
則 prefix
預設為 user
,如類內某一方法的 path
為 index
,則最終路由為 /user/index
。
需要注意的是 prefix
並非一直有效,當類內的方法的 path
以 /
開頭時,則表明路徑從 URI
頭部開始定義,也就意味著會忽略 prefix
的值。
server
表示該路由是定義在哪個 Server
之上的,由於 Hyperf
支援同時啟動多個 Server
,也就意味著有可能會同時存在多個 HTTP Server
,則在定義路由是可以通過 server
引數來進行區分這個路由是為了哪個 Server
定義的,預設為 http
。
路由引數
本框架定義的路由引數必須和控制器引數鍵名、型別保持一致,否則控制器無法接受到相關引數
Router::get('/user/{id}', 'App\Controller\UserController::info');
public function info(int $id)
{
$user = User::find($id);
return $user->toArray();
}
通過 route
方法獲取
public function index(RequestInterface $request)
{
// 存在則返回,不存在則返回預設值 null
$id = $request->route('id');
// 存在則返回,不存在則返回預設值 0
$id = $request->route('id', 0);
}
必填引數
我們可以對 $uri
進行一些引數定義,通過 {}
來宣告引數,如 /user/{id}
則聲明瞭 id
值為一個必填引數。
可選引數
有時候您可能會希望這個引數是可選的,您可以通過 []
來宣告中括號內的引數為一個可選引數,如 /user/[{id}]
。
獲取路由資訊
如果安裝了 devtool 元件,可使用 php bin/hyperf.php describe:routes
命令獲取路由列表資訊,
並且提供 path 可選項,方便獲取單個路由資訊,對應的命令 php bin/hyperf.php describe:routes --path=/foo/bar
。
HTTP 異常
在路由匹配不到路由時,如 路由找不到(404)
、請求方法不允許(405)
等 HTTP 異常,Hyperf 會統一丟擲一個 Hyperf\HttpMessage\Exception\HttpException
異常類的子類,您需要通過 ExceptionHandler 機制來管理這些異常並做對應的響應處理,預設情況下可以直接使用元件提供的 Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler
來進行異常捕獲處理,注意這個異常處理器需要您自行配置到 config/autoload/exceptions.php
配置檔案中去,並保障多個異常處理器之間的順序鏈路是正確的。
當您需要對 路由找不到(404)
、請求方法不允許(405)
等 HTTP 異常情況的響應進行自定義處理時,您可直接根據 HttpExceptionHandler
的程式碼實現您自己的異常處理器,並配置您自己的異常處理器。關於異常處理器的邏輯和使用說明,可具體查閱 異常處理