davidecesarano / embryo
Embryo 是一个用于构建 Web 应用的简单 PHP 框架。
Requires
- php: >=7.2
- davidecesarano/embryo-framework: ~3.0
- firebase/php-jwt: ^5.3
- league/flysystem: ^2.1
- phpmailer/phpmailer: ~6.0
- vlucas/phpdotenv: v2.5.1
Requires (Dev)
- phpstan/phpstan: ^0.12.59
README
您可以使用此骨架应用程序开始开发新的 Embryo Framework 3 应用程序。
- 入门
- 概念
- 应用程序
- 包
- 验证
- 会话
- 缓存
- HTTP 客户端
- 翻译
- 日志记录
- CORS
- 存储
入门
要求
- PHP >= 7.2
- URL 重写
安装
使用 Composer
$ composer create-project davidecesarano/embryo [my-app-name]
配置
Embryo 使用了 DotEnv PHP 库。在新的 Embryo 安装中,您的应用程序根目录将包含一个 .env.example 文件。当您通过 Composer 安装 Embryo 时,此文件将自动重命名为 .env。
目录结构
概念
生命周期
- 应用程序实例在
bootstrap/app.php中通过Embryo\Application类创建。在实例化过程中,Embryo 为依赖项(bootstrap/services.php)、中间件(bootstrap/middleware.php)和路由文件(在routes目录中)注册服务。应用程序构造函数接受一个可选的设置数组,该数组配置应用程序的行为(bootstrap/settings.php)。 - 在
routes目录中使用应用程序实例的路由方法定义路由。这些实例方法将路由注册到应用程序的 Router 对象中。每个路由方法都返回 Route 实例,因此您可以立即调用 Route 实例的方法来添加中间件或分配名称。 - 在
public/index.php中调用应用程序实例的run()方法。此方法启动以下过程- 进入中间件栈;
- 运行应用程序(将当前 HTTP 请求调度到适当的应用程序路由对象);
- 退出中间件栈;
- 发送 HTTP 响应。
PSR-7
Embryo 支持其请求和响应对象的 PSR-7 接口。
中间件
您可以在您的 Embryo 应用程序之前和之后运行代码,以便按您的意愿操作请求和响应对象。这被称为中间件。中间件实现了 PSR-15 中间件接口。
依赖注入容器
Embryo 使用依赖注入容器来准备、管理和注入应用程序依赖项。Embryo 支持实现 PSR-11 的容器。
应用程序
路由
您可以使用应用程序实例的路由方法定义应用程序路由。每个方法接受两个参数
- 路由模式(带有可选的占位符)
- 路由回调(闭包、
class@method字符串或['class', 'method']数组)
use Embryo\Http\Message\{Response, ServerRequest}; // GET Route $app->get('/blog/{id}', function(ServerRequest $request, Response $response, int $id) { return $response->write('This is post with id '.$id); }
Embryo 路由支持 GET、POST、PUT、PATCH、DELETE 和 OPTIONS 请求方法。每个请求方法对应于 Router 对象的方法:get()、post()、put()、patch()、delete() 和 options()。您可以使用 all() 和 map() 方法支持所有方法或特定路由方法。
查看完整文档: Embryo 路由。
注册路由文件
所有胚胎路由都定义在您的路由文件中,这些文件位于routes目录下。这些文件将由您的应用程序自动加载到boostrap/app.php文件中。如果您想创建新的路由文件,请将其添加到路由目录,并在boostrap/app.php文件中的应用实例的import()方法中注册。
$app->import([ root_path('bootstrap/services.php'), root_path('bootstrap/middleware.php'), root_path('routes/api.php'), root_path('routes/app.php'), root_path('routes/my_route_file.php') ]);
中间件
在胚胎中,您可以在app\Middleware目录中创建PSR-15中间件。您可以将中间件添加到应用程序、特定路由或路由组中。
应用程序中间件
如果您想为每个HTTP请求注册中间件,请将应用程序中间件添加到bootstrap\middleware.php。addMiddleware()方法接受一个字符串、一个数组或一个Psr\Http\Server\MiddlewareInterface的实例。
$app->addMiddleware(App\Middleware\MyCustomMiddleware::class);
路由中间件
您可以使用middleware()方法在路由上分配一个或多个中间件。middleware()方法接受一个字符串、一个数组或一个Psr\Http\Server\MiddlewareInterface的实例。
$app->get('/users', function(ServerRequest $request, Response $response) { //... })->middleware('App\MiddlewareTestMiddleware1::class', 'App\MiddlewareTestMiddleware2::class');
路由组中间件
除了路由之外,您还可以将一个或多个中间件分配给一个组,以及组内的单个路由。middleware()方法接受一个字符串、一个数组或一个Psr\Http\Server\MiddlewareInterface的实例。
$app->prefix('/api')->middleware(App\Middleware\GroupMiddlewareTest::class)->group(function($app) { $app->get('/user/{id}', function(ServerRequest $request, Response $response, int $id) { //... })->middleware(App\Middleware\RouteMiddlewareTest::class); });
控制器
您不必在路由文件中将所有请求处理逻辑定义为闭包,而是可以使用“控制器”类来组织这种行为。让我们看看一个基本控制器的例子。请注意,该控制器扩展了胚胎附带的基础控制器类。
namespace App\Controllers; use Embryo\Controller; use Embryo\Http\Message\Response; class UserController extends Controller { /** * @param int $id * @return Response */ public function show(int $id): Response { return $this->response()->write($id); } }
您可以将路由定义到该控制器方法,如下所示
use App\Controllers\UserController; $app->get('/user/{id}', [UserController::class, 'show']);
控制器必须扩展基础类。然而,您将无法访问如get()、request()和response()这样的功能。
依赖注入与控制器
您可以在控制器的构造函数中类型提示控制器可能需要的任何依赖。声明的依赖将自动解析并注入到控制器实例中
namespace App\Controllers; use Embryo\Controller; use Path\To\Service; class UserController extends Controller { /** * @var Service $service */ private $service; /** * @param Service $service */ public function __construct(Service $service) { $this->service = $service; } }
除了构造函数注入外,您还可以在控制器的方法上类型提示依赖
namespace App\Controllers; use Embryo\Controller; use Embryo\Http\Message\ServerRequest; class UserController extends Controller { /** * @param ServerRequest $request */ public function store(ServerRequest $request) { //... } }
此外,您还可以使用基础控制器类的get()方法
namespace App\Controllers; use Embryo\Controller; use Path\To\Service; class UserController extends Controller { public function show() { $service = $this->get(Service::class); //... } }
基础控制器类还可以访问PSR-7的request()和response()方法
namespace App\Controllers; use Embryo\Controller; use Embryo\Http\Message\Response; class UserController extends Controller { /** * @return Response */ public function store(): Response { $params = $this->request()->getParsedBody(); //... return $this->response()->write('Hello!'); } }
或者,您也可以访问request()和response()助手
namespace App\Controllers; use Embryo\Controller; use Embryo\Http\Message\Response; class UserController extends Controller { /** * @return Response */ public function store(): Response { $params = request()->getParsedBody(); return response()->write('Hello!'); } }
服务提供者
服务提供者是所有胚胎应用程序启动的中心位置。您的应用程序以及所有胚胎的核心服务都是通过服务提供者启动的。
编写服务
服务提供者位于app/Services目录中。所有服务提供者都扩展了Embryo\Container\ServiceProvider类,并包含一个register方法。在register方法中,您应该只将绑定项绑定到服务容器中。
namespace App\Services; use Embryo\Container\ServiceProvider; class TestService extends ServiceProvider { /** * Registers service provider. * * @return void */ public function register() { $this->container->set('test', function($container){ return 'Hello from my test service'; }); } }