adeptoas / slim3-init
为 Slim 3 提供非常方便的支持库
Requires
- php: >=7.4
- ext-json: *
- ext-mbstring: *
- php-di/php-di: ^6.3
- slim/psr7: ^1.5
- slim/slim: ^4.9
Requires (Dev)
This package is auto-updated.
Last update: 2024-09-26 14:56:53 UTC
README
这是一个围绕 Slim4 框架的非常方便的包装器,为我们提供了一些快捷方式和预填充的概念。
安装
将此添加到 composer.json
"require": { "adeptoas/slim3-init": "^4.0.0" }
请确保合并您的 require
-块!
使用
SlimInit
-
创建一个 SlimInit 实例
$app = new SlimInit();
-
设置调试头
如果请求中存在此头,则在使用默认异常处理器时将显示更多详细信息。设置为 null 以禁用此功能。
setDebugHeader(?string $header, string $expectedValue = ''): SlimInit
-
将异常映射到 HTTP 状态码
在默认异常处理器中使用时,设置异常的 HTTP 状态码。
setException(string $exception, int $statusCode): SlimInit
-
将异常映射到异常处理器
完全自定义异常处理。
$exceptionHandlerClass
必须是一个扩展Adepto\Slim3Init\Handlers\ExceptionHandler
的类的完全限定名称。setException(string $exception, string $exceptionHandlerClass): SlimInit
-
将多个异常映射到异常处理器或状态码
setException(array $exceptions, int|string $statusCodeOrHandlerClass): SlimInit
-
示例:添加错误收集服务如 Raygun、Sentry、…
要向错误收集服务发送异常,请添加异常回调
/** @var $app \Adepto\Slim3Init\SlimInit */ $app->addExceptionCallback(function(\Adepto\Slim3Init\Request $request, Throwable $t) { // Send $t to the service });
或作为类
class ExceptionCallback { public function __invoke(\Adepto\Slim3Init\Request $request, Throwable $t) { // Send $t to the service } } /** @var $app \Adepto\Slim3Init\SlimInit */ $app->addExceptionCallback(new ExceptionCallback());
-
向容器中添加内容
addToContainer(string $key, mixed $value): SlimInit
-
添加单个处理器
$className
必须是一个扩展Adepto\Slim3Init\Handlers\Handler
的类的名称。addHandler(string $className): SlimInit
-
从目录添加多个处理器
添加特定目录中的所有处理器。非递归,文件名必须是类名后跟
.php
。addHandlersFromDirectory(string $dir): SlimInit
-
添加与 Slim 4 兼容的中件
有关中件的更多信息,请参阅 Slim 的文档。
addMiddleware(callable $middleware): SlimInit
-
运行!
启动应用程序并监听传入请求。自动分配所有处理器并映射一切。
run(): Slim\App
HandlerCaller
所有模拟方法返回会发送到浏览器的文本输出。这通常是 JSON 字符串。
-
创建一个 HandlerCaller
创建一个用于
$handlerClass
的调用者。您可以留空 $baseURL,但对于一致性和兼容性,您应该将其设置为此处理器将监听的基 URL(不带路由 URL)。$caller = new HandlerCaller(string $baseURL, string $handlerClass);
-
GET
模拟带有
$headers
的$url
的 GET 请求。get(string $url, array $headers = []): string
-
POST
模拟带有
$headers
的$url
的 POST 请求,并与其一起发送$body
。如果$body
是数组,它将根据$headers
中的Content-Type
转换为表单或 JSON(默认为表单)。post(string $url, array $headers, mixed $body): string
-
PUT
模拟带有
$headers
的$url
的 PUT 请求,并与其一起发送$body
和$files
。如果$body
是数组,它将根据$headers
中的Content-Type
转换为表单或 JSON(默认为表单)。put(string $url, array $headers, mixed $body, array $files = []): string
-
PATCH
与 POST 相同,只是 HTTP 方法为 PATCH 并带有
$files
。patch(string $url, array $headers, mixed $body, $files = []): string
-
DELETE
与 POST 相同,只是 HTTP 方法为 DELETE。
delete(string $url, array $headers, mixed $body): string
Handler
要使您的 API 做些事情,您需要创建扩展 Adepto\Slim3Init\Handlers\Handler
的处理器。每个处理器必须覆盖 getRoutes(): array
以返回一个路由数组。每个处理器默认通过构造函数接收一个容器。
您的处理器实际方法的签名必须如下
public function someName(Adepto\Slim3Init\Request $request, Adepto\Slim3Init\Response $response, \stdClass $args): Adepto\Slim3Init\Response
PrivilegedHandler
与 Handler 相同,只是此类型处理器还必须覆盖 actionAllowed(string $action, array $data = []): bool
以确定给定的操作是否允许和允许。PrivilegedHandler 有一个授权客户端(用于认证的客户端,Adepto\Slim3Init\Client\Client
的实例)通过 getClient()
。
forcePermission(string $action, array $data = []): bool
强制权限。这基本上就是actionAllowed
(您必须重写)的一个别名,但如果不允许给定的权限,则抛出Adepto\Slim3Init\Exceptions\AccessDeniedException
。
路由
定义一个必须在您的处理器getRoutes()
函数返回的数组中的路由。
new Route(string $httpMethod, string $url, string $classMethod, array $arguments = [], string $name = '')
$httpMethod
:此路由使用的HTTP动词,即GET、POST、PATCH等。$url
:Slim兼容的URL模式,即/client/{client:[a-zA-Z0-9]+}
$classMethod
:要调用处理器中的方法名称。$arguments
:要添加到方法$args
的附加参数。$name
:路由名称,以便任何处理器都可以检索它。
接口:Client
-
getUsername(): string
应返回当前登录用户的用户名(如果使用了
BasicAuth
)。 -
getPermissions(): array
应返回一个包含
Adepto\Slim3Init\Client\Permission
对象的数组,用于当前登录用户(如果使用了BasicAuth
)。 -
hasPermission(string $name, array $data = []): bool;
当当前登录用户具有特定权限时返回true。您可以使用
$data
将权限与更多信息结合,即当资源信息访问应限制为某些ID时。
接口:Permission
-
getName(): string
应返回权限的名称。您有权定义名称的外观。建议使用反向域名样式,即
adepto.api.addKnowledge
。 -
getData(): array
应返回特定于该权限的信息,即可以访问的资源ID。如果没有任何信息,可以是空数组。
-
isAllowed(): bool
如果权限被允许,则返回true。
抽象:BasicAuth(中间件)
-
authorize(array $credentials): array
应返回一个包含更多信息以添加到容器的数组,例如用于与PrivilegedHandler一起使用的授权客户端。如果您要返回客户端,请确保将键设置为
PrivilegedHandler::CONTAINER_CLIENT
。如果用户无法授权,则抛出Adepto\Slim3Init\Exceptions\UnauthorizedException
。
示例
示例可在本存储库的examples/
中找到。
从SlimInit 1.0升级(使用Slim3)
尽管Slim在底层发生了很大的变化,但SlimInit对SlimInit的实际影响尽可能小。有3个重大变更和几个小变更。
重大变更
1. 处理器现在必须返回Adepto\Slim3Init\Response
的一个实例
以前,所有处理器都是使用仅Psr7兼容的接口定义的。虽然您仍然可以使用Psr7定义您处理器的参数,但返回值必须是Adepto\Slim3Init\Response
的一个实例。如果您需要转换现有的响应,请使用Response::fromSlimResponse($originalResponse)
。
2. 中间件处理从回调$next()
变为处理器
此变更直接来自Slim4,因为SlimInit没有改变此行为。以前,中间件是这样工作的
<?php /* Slim3 */ use Psr\Container\ContainerInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; class YourMiddleware { protected $container; public function __construct(ContainerInterface $container) { $this->container = $container; } public function __invoke(ServerRequestInterface $request, ResponseInterface $response, Callable $next): ResponseInterface { // Something before others run $newResponse = $next($request, $response); // Code after others have run return $newResponse; } }
现在,中间件使用RequestHandlerInterface
来处理其他代码
<?php /* Slim4 */ use Psr\Container\ContainerInterface; use Psr\Http\Server\RequestHandlerInterface; use Psr\Http\Message\ResponseInterface; use Adepto\Slim3Init\Request; class YourMiddleware { protected $container; public function __construct(ContainerInterface $container) { $this->container = $container; } public function __invoke(Request $request, RequestHandlerInterface $handler): ResponseInterface { // Something before others run $response = $handler->handle($request); // Code after others have run return $response; } }
您不再在运行其他中间件和处理器之前访问响应。
3. SlimInit
不再包含handleError
、handleNotFound
和handleMethodNotAllowed
现在,您不再在您的应用程序中覆盖这些方法来自定义500、404和405的处理,而是实现自己的ExceptionHandler
并将其分配给异常。示例
<?php use Adepto\Slim3Init\SlimInit; use Adepto\Slim3Init\Request; use Adepto\Slim3Init\Handlers\ExceptionHandler; use Psr\Http\Message\ResponseInterface; class NotFoundHandler extends ExceptionHandler { public function handle(Request $request, Throwable $t, bool $displayDetails): ResponseInterface { return $this->createResponse(404) ->withJson(['error' => 'not_found']); } } // … your $app definition /** @var $app SlimInit */ $app->setException(SomethingNotFoundException::class, NotFoundHandler::class);
您还可以覆盖现有的默认处理器404、405和500
use Adepto\Slim3Init\Exceptions\InternalErrorException; use Adepto\Slim3Init\Exceptions\MethodNotAllowedException; use Adepto\Slim3Init\Exceptions\NotFoundException; use Adepto\Slim3Init\SlimInit; /** @var $app SlimInit */ // Customize 404 $app->setException(NotFoundException::class, CustomHandler::class); // Customize 405 $app->setException(MethodNotAllowedException::class, CustomHandler::class); // Customize default handler (500) $app->setException(InternalErrorException::class, CustomHandler::class); // Customize all at once $app->setException([ NotFoundException::class, MethodNotAllowedException::class, InternalErrorException::class ], CustomHandler::class);
要使用默认异常处理器并仅自定义HTTP状态码,您可以继续分配状态码而不是处理器,就像在SlimInit 1.x中一样
use Adepto\Slim3Init\SlimInit; // … your $app definition /** @var $app SlimInit */ $app->setException(SomethingNotFoundException::class, 404);
4. SlimInit 4.1需要PHP 7.4+
SlimInit 4.1也是唯一针对PHP 7.4的版本。
5. SlimInit 4.2需要PHP 8.1+
目前处于开发中,此版本将需要PHP 8.1或更高版本。
小变更
1. SlimInit现在使用DI\Container
的扩展
它仍然与Psr7 ContainerInterface
兼容。如果您将Adepto\Slim3Init\Container
指定为类型,可以无异常地使用ArrayAccess,如下所示
/** @var $container \Adepto\Slim3Init\Container */ // Get value like normal, with exception if key was not found $value = $container->get('some-value'); // Get value array-style, with null being returned if key was not found $value = $container['some-value'];
2. Slim的便捷方法withJSON
和write
现在在Response
上有一个自定义实现
为了成为地球上最通用的库,Slim的便捷方法在ResponseInterface
上实现,而该接口没有这些方法,并且IDE可以正确识别它们,这是一个噩梦。因此,SlimInit包含了自己对这些方法的实现。
3. 新的抽象类Middleware
现在您还可以提供扩展Adepto\Slim3Init\Middleware\Middleware
的中间件。这为您提供了某些便利,例如始终可以访问容器并创建响应。
use Adepto\Slim3Init\Middleware\Middleware; use Adepto\Slim3Init\Request; use Adepto\Slim3Init\Response; use Psr\Http\Server\RequestHandlerInterface; class YourMiddleware extends Middleware { public function __invoke(Request $request, RequestHandlerInterface $handler) : Response{ return $this->createResponse(404); } }
4. new HandlerCaller(…)
已弃用
使用HandlerCaller::default(string $baseURL, string $handlerClass, $container = null)
代替。