rodriguezric / corto
基于函数的小型框架。
This package is auto-updated.
Last update: 2024-09-07 21:13:07 UTC
README
概述
Corto 是一个用于构建 REST API 的微框架。这个框架的哲学是围绕使用函数、单例和静态对象调用,以替代对全局变量的依赖。这个框架不试图制作一个大型的面向对象解决方案,而是对从请求中链式调用函数有明确观点的方法。
类
这个框架中有两个类: Request
和 Pipe
。其余的都是函数。
Request
Request
对象是一个单例,它从全局变量 $_SERVER
中提取 URI 和 HTTP 方法,并将 php://input
转换为数组。它期望输入为 JsonSerializable
。
Pipe
Pipe
是一个可调用的对象,它有一个名为 $value
的 mixed
属性。调用对象返回一个 callable
,它修改 $value
然后返回 $this
。这允许在值上创建简洁的管道函数语法。
(new Pipe(10)) (fn($x) => $x * 2); // returns 20
函数
Corto 围绕函数工作流程构建。
request
用于检索请求数据。route
用于监听 HTTP 请求,解析路径并返回响应。response
用于设置 HTTP 状态码并返回 JSON。
request
调用 request()
返回 Request
单例。在创建函数时,使用 request()->input
来访问发送的数据。
route
route
函数是框架中最复杂的。它是一个柯里化函数,首先描述 HTTP 方法。
route('GET');
这返回一个函数,它接受两个参数:路径和回调。路径是字符串,与请求的 URI 进行比较。有两种类型的路径:文本路径
和 变量路径
。
文本路径
文本路径不包含变量,并直接与 URI 进行比较。一个文本路径的例子是 /path/to/resource
。
route('GET')('/path/to/resource', ...);
变量路径
变量路径包含花括号来表示传递给回调函数的路径值。在比较 URI 之前,变量路径被转换为正则表达式。一个变量路径的例子是 /path/to/resource/{variable}
。
route('GET')('/path/to/resource/{variable}', ...);
注意 花括号之间的单词没有意义,花括号之间可以使用的任何单词都可以用来表示该值。如果变量路径中包含多个变量,它们将按照顺序传递给回调。
response
响应函数是一个柯里化函数,它从 HTTP 响应代码开始。该函数返回的调用者期望 array
或 JsonSerializable
数据。它设置 HTTP 响应代码,然后将数据转换为 JSON,以 JSON 格式回显。回显完成后,它 退出
。
这个函数与 JSON 输出紧密耦合,并且终止程序。我对这些决定感到满意,因为框架严格定义了单一目的:根据请求交付 JSON 响应
。
示例
以下是如何实现 函数
部分中描述的功能的示例。这应该放在您的公共脚本中,例如 index.php
。
<?php declare(strict_types=1); include __DIR__ . "/../vendor/autoload.php"; use function Rodriguezric\Corto\{route, route_chain, response, request}; set_exception_handler( function($exception) { file_put_contents("php://stderr", $exception->getMessage()); return response(400)(['error' => 'Exception thrown.']); } ); $hello = fn() => response(200)(['message' => 'Hello']); route('GET')('/', $hello); $create_person = function() { if (request()->is_missing('name')) { return response(400)(['error' => 'Missing arguments']); } $name = request()->input['name']; return response(200)(['message' => "Created new person with name {$name}"]); }; route('POST')('/person', $create_person); $update_person = fn($id) => response(200)(['message' => "Updated person with id: {$id}"]); route('PUT')('/person/{id}', $update_person); response(400)(['message' => 'Resource not found.']);
我将解释示例中的某些部分,以说明它们的目的。
异常处理
set_exception_handler( function($exception) { file_put_contents("php://stderr", $exception->getMessage()); return response(400)(['error' => 'Exception thrown.']); } );
本段代码将向请求者发送带有JSON响应的400响应。
{ "error": "Exception thrown." }
同时,在服务器端,它将实际异常消息发送到标准错误。我将这两个消息分开,以便我可以在容器日志中查看错误,向请求者告知发生了错误,但仍然隐藏详细信息。
请求示例
GET
$hello = fn() => response(200)(['message' => 'Hello']); route('GET')('/', $hello);
本节设置了一个简单的GET
请求,并将一个函数作为可调用对象传递。该函数返回response
调用的结果。函数response
回显其结果并终止脚本。
POST
$create_person = function() { if (request()->is_missing('name')) { return response(400)(['error' => 'Missing arguments']); } $name = request()->input['name']; return response(200)(['message' => "Created new person with name {$name}"]); }; route('POST')('/person', $create_person);
本节设置了一个POST
请求。可调用对象测试请求以确保请求中包含name
字段。如果缺少该字段,它将发送400 HTTP响应代码,并带有表示错误的JSON消息。
{ "error": "Missing arguments." }
如果请求中包含name
属性,它将使用该值创建其响应。这个例子是虚构的,因为它只显示提供名称的JSON,通常我们会在这里执行我们的工作并发送包含有用信息的响应。
PUT
$update_person = fn($id) => response(200)(['message' => "Updated person with id: {$id}"]); route('PUT')('/person/{id}', $update_person);
在这个例子中,我们使用了PUT
请求。这是第一个使用变量路径
的例子。传递给路由函数的可调用对象必须有一个参数,以便使用路径中描述的变量。