kaawikaconnell / fruiter
一个简单的路由库。高度受函数式编程的启发。
Requires
- php: ^7.1
Requires (Dev)
- phpunit/phpunit: ^7.5
This package is auto-updated.
Last update: 2024-09-13 09:36:04 UTC
README
一个简单的路由库。高度受函数式编程的启发。跳转到 安装。
这个项目是为了挑战我自己而创建的。我在之前玩过Laravel,并使用了他们的路由器,但从未真正有信心理解它在做什么。我怀疑编写这个库将不会让我完全理解Laravel在做什么(因为我编写它之前没有麻烦地去查看它的源代码),但我喜欢从头开始编写一个路由库,尝试自己解决遇到的所有问题。我还用这个项目来探索函数式编程。起初一切都是高阶函数(一个要么接受一个函数作为参数要么返回一个函数的函数),但最终我转向了类。我仍然遵循了一些函数式原则来构建这个项目。除此之外,安装和使用说明如下。
安装
您可以通过Composer安装此包,或者下载它并将 fruiter.php
包含在您的程序中。
通过Composer安装
在您的项目根目录中运行以下命令
composer require kawikaconnell/fruiter
手动安装
- 点击右上角的绿色 克隆或下载。
- 选择一个选项(通过https或ssh克隆,在桌面打开,或下载zip文件)
- 确保代码在项目根目录中某个地方
- 需要它
require_once '/where/ever/you/put/it/fruiter.php';
用法
以下是一个基本的用法示例
<?php declare(strict_types=1); require_once '/where/ever/you/put/it/fruiter.php'; use KawikaConnell\Fruiter\Route; use function KawikaConnell\Fruiter\uri_router; use function KawikaConnell\Fruiter\get_path_from_url; $index = new Route('/', function() { return 'Hello World!'; }); $greeter = new Route('/hello/{name}', function(array $arguments) { return "Hello {$arguments['name']}"; }); $routes = [$index, $greeter]; $path = get_path_from_url($url); $result = uri_router($routes, $path); if ($result === null) { http_response_code(404); echo "404 ERROR"; die(); } $action = $result->getRoute()->getAction(); $arguments = $result->getArguments(); echo $action($arguments);
RoutingResult
KawikaConnell\Fruiter\RoutingResult
是一个类,用于保存
- 匹配查询的路由,
- 以及从查询中提取的参数。您可以通过
getRoute()
和getArguments()
方法访问这些信息
$routingResult = new KawikaConnell\Fruiter\RoutingResult(new Route(...), []); $routingResult->getRoute(); // Route $routingResult->getArguments(); // array
这是Fruiter中所有路由器返回的内容。如果您正在编写会修改 RoutingResult
中数据的代码,您将不得不创建一个新的实例,因为它是不可变的。假设您想将 RoutingResult
中的每个参数都追加 '-ish',
$routingResult = new KawikaConnell\Fruiter\RoutingResult( new Route('/{person}/{company}', ...), ['person' => 'John', 'company' => 'John Co'] ); function ishizeArguments($routingResult) { $arguments = $routingResult->getArguments(); foreach ($arguments as $argumentName => $argument) { $arguments[$argumentName] = $argument.'-ish'; } return new KawikaConnell\Fruiter\RoutingResult($routingResult->getRoute(), $arguments); } $routingResult = ishizeArguments($routingResult); $routingResult->getArguments(); // ['person' => 'John-ish', 'company' => 'John Co-ish']
Route
KawikaConnell\Fruiter\Route
是一个类,用于保存一个模式和一个操作。您可以通过 getPattern()
和 getAction
方法访问这些信息。
$route = new KawikaConnell\Fruiter\Route('/', function(...) {...}); $route->getPattern(); // "/" (string) $route->getAction(); // Closure
此类不会强制查询匹配模式,您需要在调用操作之前确保查询是否匹配模式。Fruiter中的所有路由器都会为您执行此操作,因为它们返回匹配查询的路由。
Matcher
KawikaConnell\Fruiter\Matcher
是Fruiter的核心组件。它用于确定查询是否匹配模式,并从查询中提取参数,正如模式中定义的那样。匹配器将模式和查询分割成块,并比较查询中的块与模式中的对应块以确定它们是否匹配。
示例
以下所有示例中,假设所有匹配的分隔符都是 '/'。
无参数的模式
无参数的模式需要完全匹配。
以下示例产生匹配
pattern = '/about'
query = '/about'
-----------------------
matches = true
argumentsExtracted = []
以下示例不产生匹配
pattern = '/about'
query = '/products'
-----------------------
matches = false
argumentsExtracted = []
必需参数
默认情况下,参数是必需的。它们定义如下 {this}
,其中 'this' 是参数名称。如果从查询中提取了一个参数,则其键将作为模式中定义的参数名称。
pattern = '/page/{page}'
query = '/page/about-us'
-----------------------
matches = true
argumentsExtracted = [
'page' = 'about-us'
]
带有参数的模式比没有参数的模式要宽松,因为唯一的要求是提供值。
可选参数
可选参数是可选的,因此如果查询缺少一个片段,并且该片段是可选的,则查询仍然与模式匹配。
pattern = '/project/{projectId}/{?taskId}'
query = '/project/123'
-----------------------
matches = true
argumentsExtracted = [
projectId = 123
taskId = null
]
可以连续有多个可选参数。
pattern = '/project/{?projectId}/{?taskId}'
query = '/project'
-----------------------
matches = true
argumentsExtracted = [
projectId = null
taskId = null
]
如果未提供可选参数的值,则匹配器将分配 null
作为参数值。因此,可选参数总是被填充。在可选参数后面跟有必需参数时,需要将该可选参数分配一个值,因为它从左到右评估查询,检查该顺序中的每个参数。这使得在可选参数之后如果有必需参数,则可选参数变为必需。
pattern = '/checkedFirst/{?checkedSecond}/{checkedThird}'
query = '/checkedFirst/this'
-----------------------
matches = false // because checkedThird doesn't have a corresponding chunk in the query.
argumentsExtracted = []
想法
- 创建一个同时检查匹配方法和处理HTTP错误的HTTP路由器。
- 创建一个命令行应用程序路由器,该路由器考虑了短标志、长标志和标志参数的标志。