fostam / simplerouter
简单的路由器,主要用于API后端,支持CORS
Requires
- php: >=5.6
Requires (Dev)
- phpunit/phpunit: ^5.5|^6.5
README
简单的PHP路由器,主要用于构建API后端。
特性
- 易于配置
- 响应和错误处理
- 从URL、GET/POST参数或JSON负载中获取参数输入
- CORS支持
安装
安装SimpleRouter最简单的方法是使用 composer
$> composer require fostam/simplerouter
用法
这是一个典型的“处理程序”的样子
<?php include "vendor/autoload.php"; use Fostam\SimpleRouter\Response; use Fostam\SimpleRouter\Router; use Fostam\SimpleRouter\Http; use Fostam\SimpleRouter\Exception\InternalApiException; use Fostam\SimpleRouter\Exception\UserApiException; $router = new Router(); try { // all URLs must be prefixed with this string $router->setOption(Router::OPT_REQUEST_PATH_PREFIX, '/myproject/api'); // send permissive cross origin resource sharing headers $router->setOption(Router::OPT_CORS_PERMISSIVE, true); // by default, send the response with application/json content type $router->setOption(Router::OPT_RESPONSE_TYPE_DEFAULT, Response::TYPE_JSON); // routes $router->createRoute('/users', Http::METHOD_GET, \MyProject\GetUsers::class); $router->createRoute('/users/{id}', Http::METHOD_GET, \MyProject\GetUsers::class); $router->createRoute('/users', Http::METHOD_POST, \MyProject\CreateUser::class); // resolve $router->resolve(); } catch (UserApiException $e) { // error messages are automatically passed back as JSON } catch (InternalApiException $e) { // a generic error message is passed back as JSON; trigger the actual errors // (e.g. a failed database query) that should not be publicly visible, but // logged internally error_log($e); } $router->sendResult();
这可以是获取用户的一个(非常简化)处理器类
class GetUsers extends Processor { public function execute() { $userID = $this->getPathParam('id'); if (!is_numeric($userID)) { throw new UserApiException('userID must be a number', Http::CODE_BAD_REQUEST, $e); } try { $data = $this->myUserModel->getUser(intval($userID)); } catch (\Exception $e) { throw new InternalApiException("error getting data for user {$userID}", Http::CODE_INTERNAL_SERVER_ERROR, $e); } $this->setResponseData( [ 'data' => $data ] ); } }
创建用户的示例类
class CreateUser extends Processor { public function execute() { $data = $this->getJSONPostData(); if (!isset($data['name'])) { throw new UserApiException("parameter 'name' is missing"); } try { $userID = $this->myUserModel->createUser($data); } catch (\Exception $e) { throw new InternalApiException("error creating user", Http::CODE_INTERNAL_SERVER_ERROR, $e); } // send "201 Created" $this->setResponseCode(Http::CODE_CREATED); // send the location of the new object as header // here: 'Location: /myproject/api/users/123' (for $userID=123) $this->getResponseObject()->setLocationPath($this->getPath() . '/' . $userID); } }
参考
路由器
setOption()
Router setOption($option, $value) 设置路由器选项。返回路由器对象以允许链式调用。以下选项可用:
addRoute()
Route addRoute(Route $route)
将一个 Route 对象添加到路由列表。为了方便,返回路由对象以允许直接调用 Route 方法。
createRoute()
Route createRoute(string $path, string $method, mixed $processor)
从给定的参数创建一个 Route 对象,将其添加到路由列表,并返回它。有关参数的描述,请参阅 Route 文档。
resolve()
void resolve(string $path = '', string $method = '')
解析给定的路径/方法并执行匹配的处理器。如果 $path 为空,则使用 $_SERVER['SCRIPT_NAME'] 作为路径。如果 $method 为空,则使用 $_SERVER['REQUEST_METHOD'] 作为方法。
sendResult()
void sendResult()
发送结果。这包括HTTP状态码、HTTP头(包括内容类型)和正文。内容类型头和正文格式取决于配置的响应类型。
getResponseObject()
Response getResponseObject()
获取 Response 对象。响应对象表示调用 sendResult() 时发送的内容。
Route
构造函数
Route __construct(array $config)
当路由配置来自动态源时,例如来自数据库,构造函数是创建路由的首选方法。
它使用给定的关联数组 $config 构建一个路由对象。以下配置键可用:
path 是定义此路由何时匹配的端点。在比较实际路径时,如果已配置,则前缀为 Router::OPT_REQUEST_PATH_PREFIX。
method 是需要与路径匹配的HTTP方法,例如 Http::METHOD_GET 或 Http::METHOD_POST。
如果路径和方法都匹配,则调用 processor。定义处理器有三种不同的情况
- 类名 - 如果类有无参构造函数,则这适合,因为实例化是在使用类时完成的
- 由一个类名和另一个包含构造函数参数的数组组成的数组 - 当构造函数需要参数时可以使用此方法
- 对象 - 当处理器对象预先创建时适合
在任意一种情况下,传递的类/对象需要扩展抽象 Processor 类。
create()
Route ::create(string $path, string $method, mixed $processor)
从参数创建一个 Route 对象的静态方法。当路由定义是硬编码在PHP中时,首选创建路由的方式是使用 create() 方法。有关参数的描述,请参阅构造函数。
Processor
getPath()
string getPath()
获取此处理器配置的路径。
getMethod()
string getMethod()
获取此处理器配置的HTTP方法。
getResponseObject()
Response getResponseObject()
获取处理器完成后将用于创建响应的响应对象。
setResponseCode()
void setResponseCode(int $code)
设置HTTP响应代码,例如 Http::CODE_OK (200)。
是 getResponseObject()->setCode($code) 的简写。
setResponseType()
void setResponseType(string $type)
设置HTTP响应类型,例如 Response::TYPE_JSON。这可以是 Response 类中的 TYPE_ 常量之一,或任何有效的MIME类型字符串,例如 application/xml。如果没有设置响应类型,路由器将发送默认响应类型(如果已设置则为 Router::OPT_RESPONSE_TYPE_DEFAULT),如果没有设置默认值,则发送 text/html。
是 getResponseObject()->setType($type) 的简写。
setResponseData()
void setResponseData(mixed $data)
设置主体数据。这可以是用于 Response::TYPE_JSON 响应类型的数组,或用于 Response::TYPE_HTML 或任何其他响应类型的字符串。
是 getResponseObject()->setData($data) 的简写。
getPathParams()
string[] getPathParams()
获取所有路径参数值作为键/值对。
示例
$router->createRoute('/test/{id}/user/{name}', Http::METHOD_GET, Test::class); $router->resolve('/test/123/user/john', Http::METHOD_GET);
在 Test 处理器调用中对 getPathParams() 的调用将返回
array(2) { 'id' => string(3) "123" 'name' => string(4) "john" }
getPathParam()
string getPathParam(string $param)
获取单个参数的路径参数值。对于上面的示例,getPathParam('name') 将返回 john。
getQueryParams()
string[] getQueryParams()
以键/值对的形式返回查询参数。这与PHP的 $_GET 超全局变量等效。
getQueryParam()
string getQueryParam(string $param)
获取单个参数的查询参数值。
getPostParams()
string[] getPostParams()
以键/值对的形式返回POST参数。这与PHP的 $_POST 超全局变量等效。
getPostParam()
string getPostParam(string $param)
获取单个参数的POST参数值。
getJSONPostData()
mixed getJSONPostData()
当POST、PUT或PATCH调用的主体包含JSON字符串时,可以将其结构检索为PHP数组。
示例
curl 'https://example.com/test' -X POST -d '{"id": 123, "name": "john"}'
对 getJSONPostData() 的调用将返回此数组
array(2) { 'id' => int(123) 'name' => string(4) "john" }
Response
setCode()
void setCode(int $code)
设置HTTP响应代码,例如 Http::CODE_OK (200)。
getCode()
int getCode()
获取当前响应代码。
setType()
void setType(string $type)
设置HTTP响应类型,例如 Response::TYPE_JSON。这可以是 Response 类中的 TYPE_ 常量之一,或任何有效的MIME类型字符串,例如 application/xml。如果没有设置响应类型,路由器将发送默认响应类型(如果已设置则为 Router::OPT_RESPONSE_TYPE_DEFAULT),如果没有设置默认值,则发送 text/html。
getType()
int getType()
获取当前响应代码。
setData()
void setData(mixed $data)
设置主体数据。这可以是用于 Response::TYPE_JSON 响应类型的数组,或用于 Response::TYPE_HTML 或任何其他响应类型的字符串。
getData()
mixed getData()
获取当前数据。
setLocationPath()
void setLocationPath(string $path)
设置位置路径。如果设置了 Router::OPT_REQUEST_PATH_PREFIX,则在此路径前加上前缀,然后作为 Location 标头发送。
示例
$router->setOption(Router::OPT_REQUEST_PATH_PREFIX, '/test/api'); ... $this->getResponseObject->setLocationPath('/users'); ... Location: /test/api/users
getLocationPath()
string getLocationPath()
获取位置路径。
setHeader()
void setHeader(string $header, string $value, bool $append = false)
将HTTP头 $header 设置为值 $value。如果 $append 为 true 并且之前已设置该头,则将添加一个额外的相同头的头行。
isHeaderSet()
bool isHeaderSet(string $header)
返回是否设置了头 $header。
getHeader()
array getHeader(string $header)
获取头 $header。返回一个包含以下元素的数组
Response::HEADER_NAME:头的名称,例如 Content-TypeResponse::HEADER_VALUES:代表值的字符串数组
getHeaders()
array getHeaders()
获取所有头。它返回一个条目数组,如 getHeader() 返回。
clearHeader()
void clearHeader(string $header)
清除头 $header。
clearHeaders()
void clearHeaders()
清除所有标题。
addResponseData()
void addResponseData(string $key, string $value, string $separator = '.')
将数据添加到响应数组(用于JSON响应类型)。子数组键可以用$separator字符串分隔。
示例
addResponseData('data.user.name', 'John')
将设置此值
{
"data": {
"user": {
"name": "John"
}
}
}
corsSetOrigin()
void corsSetOrigin(string $origin)
将Access-Control-Allow-Origin设置为$origin,例如使用corsSetOrigin('*')允许所有来源。
corsAddOrigin()
void corsAddOrigin(string $origin)
如果需要多个来源,可以添加一个来源,例如corsAddOrigin('example.org')。来源列表与Origin请求头进行比较。匹配时,将Access-Control-Allow-Origin设置为匹配的来源。
corsGetOrigins()
array corsGetOrigins()
获取允许的来源列表。
corsAllowCredentials()
void corsAllowCredentials(bool $allowed)
用于设置Access-Control-Allow-Credentials头。
corsAddAllowedHeader()
void corsAddAllowedHeader(string $header)
将头添加到用于Access-Control-Allow-Headers的允许头列表中。
corsAddAllowedHeaders()
void corsAddAllowedHeaders(string[] $headers)
设置允许头的数组。
corsSetMaxAge()
void corsSetMaxAge(int $maxAgeSeconds)
设置用于Access-Control-Max-Age头的最大秒数。