rawebone / razor-library
提供核心Razor处理
Requires
- php: >=5.4
- rawebone/injector: 1.*
- symfony/http-foundation: 2.4.*
Requires (Dev)
- braincrafted/json: 0.2
- phpspec/prophecy-phpunit: v1.0.1
- phpunit/phpunit: 4.1.*
Suggests
- braincrafted/json: Required if using the JSON Extension
This package is not auto-updated.
Last update: 2024-09-24 02:23:55 UTC
README
Razor是一个基于REST概念的轻量级微框架。它类似于许多项目,如Slim和Silex,但设计得更加易于使用,这是基于个人偏好的。
如上所述,该框架专注于RESTful Web应用程序。假设我们正在开发必做的TODO应用程序,我们将在API中有一个表示TODO项目集合的端点,或者更准确地说,是资源。
在Razor中建模,我们将在面向Web的文件夹中创建一个名为todos.php
的文件,其中包含以下代码
<?php // File: todos.php require_once "/path/to/vendor/autoload.php"; use Razor\EndPoint; (new EndPoint()) ->run();
我们可以把这个文件看作是我们的资源集合;即如果我们想要添加、编辑、获取或删除TODO项,那么这些更改将通过这个文件来实现。Razor针对这种思维方式,因此所有与资源相关的逻辑都被封装在EndPoint
对象中。为了能够对资源执行操作,我们必须将代表HTTP请求方法的槽中的代理或闭包分配给,或者更简单地说
<?php // File: todos.php require_once "/path/to/vendor/autoload.php"; use Razor\EndPoint; (new EndPoint()) ->get(function () { // Hey, that was easy! }) ->run();
熟悉其他微框架格式的用户应该会认出这种语法。本质上,当Web浏览器发起HTTP GET请求时,传递给get()
方法的代理(或闭包)中的代码会被调用。每个主要的HTTP动词都有一个方法调用,未来可能还会支持更多。
太好了!因此,我们的客户端可以通过浏览器访问我们的todo.php
页面,但他们看到的是...什么也没有。让我们通过向浏览器发送消息来解决这个问题
<?php // File: todos.php require_once "/path/to/vendor/autoload.php"; use Razor\EndPoint; use Razor\Services\Http; (new EndPoint()) ->get(function (Http $http) { return $http->response->standard("Hello, world!"); }) ->run();
现在当客户端连接时,他们将收到消息Hello, world!
。你可能已经注意到,你不必在这个文件中指定$http
对象的存在,并且它已经作为参数传递给代理。这里发生的事情被称为服务注入。
服务是提供应用程序某些功能的对象或值。当Razor决定调用HTTP GET请求的代理时,它会检查指定的参数,看看是否能提供它们。如果可以,它将在调用代理时注入这些参数。如果你有AngularJS背景,这对你来说可能很自然,如果没有,这可能会有些陌生。目标是使你的代理无状态,即不是这个
<?php // File: todos.php require_once "/path/to/vendor/autoload.php"; use Razor\EndPoint; use Razor\Services\Http; $http = new Http(/* Have to supply all the arguments here ... */); (new EndPoint()) ->get(function () use ($http) { return $http->response->standard("Hello, world!"); }) ->run();
这是因为,首先,你总是必须创建对象或编写相当丑陋的代码来懒加载它,其次是因为function () use (...)
非常简短、丑陋,并且随着时间的推移变得难以维护和阅读。
在这个特定的例子中,$http
是Razor附带的一个服务,但你也可以在你的代码中使用服务。假设我们已经有一个处理todo数据库管理的对象,我们可以在代码中这样指定
<?php // File: todos.php require_once "/path/to/vendor/autoload.php"; use Razor\Razor; use Razor\EndPoint; use Razor\Services\Http; Razor::environment() ->services() ->register("todoRepo", function () { return new TodoRepo(/* ... */); }); (new EndPoint()) ->get(function (Http $http, TodoRepo $todoRepo) { $id = $http->request->get("id"); $data = $todoRepo->get($id); return $http->response->json($data); }) ->run();
在这里,我们使用代理将服务与框架的Environment
注册。然后在我们的代码中,我们将这个服务指定为依赖项。重要的是要注意,我们使用的是名称todoRepo
来查找服务,而不是类型提示。这是因为我们可能会遇到多个具有相同类型需要注入的对象,比如使用相同API的不同日志对象。
同样重要的是要注意,这个代理也可以接收注入的服务,比如
Razor::environment() ->services() ->registerMany(array( "conn", function () { return new PDO(/* ... */); }, "todoRepo", function (PDO $conn) { return new TodoRepo($conn); } ));
注意。建议您将这些服务注册移动到bootstrap.php
文件中,这样随着您的应用程序不断增长,您可以更好地管理它。
假设您想将此应用程序公开到网络上,但您想确保有安全措施。您可以公开一个服务来处理此操作,但无疑会导致大量模板代码。因此,该框架提供了众所周知的中间件概念。
中间件是一个小对象,设计在您的代理之前调用,并执行请求过滤或响应修改。这意味着您可以编写小段功能代码,并从这些代码中组合您的处理。一个中间件的例子是
// File: src/SecurityMiddleware.php use Razor\Middleware; use Razor\Services\Http; class SecurityMiddleware extends Middleware { public function __invoke(Http $http) { if (!$http->request->isSecure()) { return $http->response->standard("Whoa! Your connection is not secure!", 400); } return $this->invokeDelegate(); } }
然后我们可以通过以下方式使用SecurityMiddleware
<?php // File: todos.php require_once "/path/to/vendor/autoload.php"; use Razor\EndPoint; use Razor\Services\Http; (new EndPoint()) ->get(new SecurityMiddleware(function (Http $http, TodoRepo $todoRepo) { $id = $http->request->get("id"); $data = $todoRepo->get($id); return $http->response->json($data); })) ->run();
因此,SecurityMiddleware
将被首先调用,如果连接安全,它将随后调用我们的应用程序逻辑来处理GET
请求。我们还可以将中间件串联起来
<?php // File: todos.php require_once "/path/to/vendor/autoload.php"; use Razor\EndPoint; use Razor\Services\Http; (new EndPoint()) ->get(new SecurityMiddleware(new EnsureJsonMiddleware(function (Http $http, TodoRepo $todoRepo) { $id = $http->request->get("id"); $data = $todoRepo->get($id); return $http->response->json($data); }))) ->run();
关于Razor
该框架旨在为开发者提供便利。您希望编写结构良好的代码,但也需要为项目中每一行代码提供合理的解释?Razor尽可能地轻量级,使用简单的API进行服务注入,并在其HTTP服务中使用备受信赖的Symfony HTTP基础库。
您希望编写易于维护的代码?服务允许您在不增加应用程序逻辑中的模板代码的情况下,保持共享逻辑的可访问性。将应用程序逻辑保留在URL端点,这样您可以轻松地识别正在发生的事情。
总的来说,Razor旨在以一种优雅的方式让您处理HTTP请求,而不添加冗余。如果它符合您的工作流程,那么祝您好运!
安装
安装通过Composer进行,将Razor添加到您的依赖项中
{ "require": { "rawebone/razor-library": "dev-master" } }
一旦项目稳定,将有两个分支可供安装
- 1.x.y
- 1.x.y-compat
compat
分支将允许PHP5.3及以上版本的用户使用该框架,而主分支将是PHP5.4及以上版本。
请将所有拉取请求基于master分支。
许可
MIT License,尽情使用。