Embryo 是一个用于构建 Web 应用的简单 PHP 框架。

3.2.1 2021-06-25 09:58 UTC

This package is auto-updated.

Last update: 2024-09-05 18:39:23 UTC


README

您可以使用此骨架应用程序开始开发新的 Embryo Framework 3 应用程序。

入门

要求

  • 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.phpaddMiddleware()方法接受一个字符串、一个数组或一个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';
        });
    }
}

注册服务

模型

视图

验证