lucinda/console-mvc

适用于PHP应用的MVC模式,通过MVC模式处理控制台请求到响应的超高性能API

v2.0.6 2022-11-11 21:00 UTC

This package is auto-updated.

Last update: 2024-09-12 01:00:33 UTC


README

目录

关于

此API是一个 骨架(需要开发者绑定),用于高效地处理控制台请求到服务器响应,使用MVC版本,其中视图和模型应相互独立,而控制器根据用户请求在两者之间进行调解。以模块化、效率和简洁为基础设计,API是对象和事件导向的:类似于JavaScript,它允许开发者在处理过程中绑定在预定义事件达到时执行的逻辑。

diagram

API只执行标准MVC逻辑,因此可能需要构建在顶层框架上以添加更多功能(例如:数据库连接)。为了使用它,开发者需要以下步骤

  • 配置:设置一个XML文件,在此文件中配置此API
  • 绑定点:将XML/代码中定义的用户定义组件绑定到API原型,以获得必要的功能
  • 初始化:实例化FrontController,一个Runnable,它能够根据上述内容在以后处理请求到响应
  • 绑定事件:设置Runnable类,当在处理过程中达到预定义事件时,将被实例化和运行
  • 配置共享变量:扩展Attributes类,封装特定于项目的变量,以便在事件监听器和控制器之间共享
  • 处理:在FrontController中调用run方法,最终处理请求到响应,触发上述事件(如果有)

API完全符合PSR-4规范,仅需要Abstract MVC API进行基本MVC逻辑、PHP7.1+解释器和SimpleXML扩展。要快速了解其工作原理,请查看

  • 安装:描述了如何在您的计算机上安装API,考虑到上述步骤
  • 运行请求:描述如何使用已安装和配置的API运行控制台请求
  • 参考指南:描述所有与开发者相关的API类、方法和字段
  • 单元测试:API具有100%的单元测试覆盖率,使用UnitTest API而不是PHPUnit以获得更大的灵活性
  • 示例:基于FrontController单元测试展示API功能的深度示例

内部所有类都属于 Lucinda\ConsoleSTDOUT 命名空间!

配置

要配置此API,您必须有一个包含以下标签的XML文件

  • 应用:(必填)在一般基础上配置您的应用程序
  • 解析器:(必填)配置您的应用程序能够解析响应的格式
  • 路由:(必填)配置将请求资源绑定到控制器和视图的路由

应用程序

标签文档完全由继承的Abstract MVC API 规范 覆盖!由于此API的STDIN由HTTP(s)请求组成,因此 default_route 属性的值必须指向 index(主页)以处理没有路由的请求。

解析器

标签文档完全由继承的Abstract MVC API 规范 覆盖!

路由

此标签的最大语法是

<routes>
    <route id="..." controller="..." view="..." format="..."/>
    ...
</routes>

大多数标签逻辑已经由Abstract MVC API 规范 覆盖。以下额外的观察需要指出

  • id:(必填)当运行API时,通过 第一个控制台参数 识别的请求路由!
  • controller:(可选)用户定义的PS-4自加载兼容类(包括命名空间)的名称,该类将基于模型缓解请求和响应。
    该类必须是 控制器 实例!

标签示例

<routes>
    <route id="users" controller="Lucinda\Project\Controllers\UsersSynchronization" view="users"/>
    <route id="groups" controller="Lucinda\Project\Controllers\GroupsSynchronization" view="groups">
</routes>

^ 在 应用程序 XML标签中定义由default_route属性定义的路由是强制性的!

如果请求没有路由,则使用 默认 路由。然而,如果请求包含与 id 不匹配的路由,则抛出 RouteNotFoundException

绑定点

为了保持灵活性和实现最高性能,API不假设任何绝对必需之外的东西!它相反为开发者提供了绑定到其原型的能力,以获得某些功能。

声明式绑定

它为开发者提供了一种通过XML 声明式地将其原型类/接口绑定到其上的能力

程序性绑定

它为开发者提供了一种通过 FrontController 构造函数 程序性地将其原型绑定到其上的能力

和addEventListener方法(见:绑定事件部分)!

执行

初始化

开发人员完成设置API配置的XML后,他们最终可以通过实例化FrontController来初始化它。

除了实现Runnable接口所必需的run方法外,该类还提供了以下公共方法:

其中

  • $documentDescriptor:XML配置文件的相对位置。例如:“configuration.xml”
  • $attributes:请参阅配置共享变量
  • $type:事件类型(请参阅下面的绑定事件),由枚举EventType封装
  • $className:监听器的类名,包括命名空间和子文件夹,在Attributes实例化时定义的文件夹中找到。

示例

$handler = new FrontController("configuration.xml", new MyCustomAttributes("application/event_listeners");
$handler->run();

绑定事件

如上所述,API允许开发人员通过上述addEventListener方法将监听器绑定到处理生命周期事件。每种事件类型对应一个抽象的Runnable

监听器必须扩展匹配的事件类并实现必需的run方法,该方法包含在事件触发时将执行的逻辑。它们必须在run方法运行之前进行注册

$handler = new FrontController("stdout.xml", new FrameworkAttributes();
$handler->addEventListener(EventType::APPLICATION, Lucinda\Project\EventListeners\Logging::class);
$handler->run();

要了解事件监听器的定位方式,请查看规范

配置共享变量

API允许事件监听器设置将被提供给后续事件监听器和控制器的变量。对于每个变量都有一个

  • setter:由事件监听器运行一次
  • getter:由后续事件监听器和控制器运行

API提供了Attributes,它包含每个网站都必须扩展的基础,以便设置自己的变量。除非您的网站非常简单,否则将需要开发人员扩展此类并添加更多变量,为此必须定义setter和getter!

处理

完成上述步骤后,开发人员最终可以通过FrontControllerrun方法处理请求到响应,该方法

所有由开发者负责的组件(ControllerLucinda\MVC\ViewResolver以及自身的事件监听器),都实现了Runnable接口。

安装

首先选择一个文件夹,然后在控制台中使用以下命令

composer require lucinda/console-mvc

将上述文件夹重命名为DESTINATION_FOLDER,然后在项目根目录下创建一个configuration.xml文件,用于保存配置设置(见上文的配置),以及一个index.php文件(见上文的初始化),其中包含以下代码

$controller = new Lucinda\ConsoleSTDOUT\FrontController("configuration.xml", new Attributes("application/events"));
// TODO: add event listeners here
$controller->run();

运行请求

现在您已在您的机器上安装了项目,请转到DESTINATION_FOLDER,打开控制台/终端并输入

php index.php ROUTE PARAM1 PARAM2 ...

其中

  • ROUTE:要处理的路由(必须与路由 XML子标签相匹配)
  • PARAM1, ...:要发送到路由的参数,在控制器/监听器中可访问为:$this->request->parameters

单元测试

有关测试和示例,请检查API源中的以下文件/文件夹

  • test.php:在控制台运行单元测试
  • unit-tests.xml:设置单元测试并模拟"loggers"标签
  • tests:src文件夹中类别的单元测试

参考指南

这些类由API完全实现

  • Request:封装请求信息(路由、参数、用户信息等)

除了在绑定事件中提到的类之外,以下抽象类需要由开发者扩展,以获得能力

类Request

Request封装了基于超全局变量($_SERVER, $_GET, $_POST, $_FILES)检测到的用户请求信息,并定义了以下与开发者相关的公共方法

类Request UserInfo

Request\UserInfo封装了关于发起请求的用户的信息,并定义了以下与开发者相关的公共方法

抽象类EventListeners Start

抽象类EventListeners\Start实现了Runnable),并监听在读取配置 XML之前执行的事件。

开发人员需要实现一个run方法,在该方法中,他们可以访问通过构造函数由API注入的以下受保护字段:

START监听器的一个常见示例是设置开始时间,以便稍后对处理持续时间进行基准测试。

class StartBenchmark extends Lucinda\ConsoleSTDOUT\EventListeners\Start
{
    public function run(): void
    {
        // you will first need to extend Application and add: setStartTime, getStartTime
        $this->attributes->setStartTime(microtime(true));
    }
}

抽象类 EventListeners 应用程序

抽象类EventListeners\Application实现了Runnable接口,并监听在读取配置 XML之后的执行事件。

开发人员需要实现一个run方法,在该方法中,他们可以访问通过构造函数由API注入的以下受保护字段:

待办事项:使用示例

抽象类 EventListeners 请求

抽象类EventListeners\Request实现了Runnable接口,并监听在创建Request对象之后的执行事件。

开发人员需要实现一个run方法,在该方法中,他们可以访问通过构造函数由API注入的以下受保护字段:

待办事项:使用示例

抽象类 EventListeners 响应

抽象类EventListeners\Response实现了Runnable接口,并监听在设置Lucinda\MVC\Response主体后、提交给调用者之前的执行事件。

开发人员需要实现一个run方法,在该方法中,他们可以访问通过构造函数由API注入的以下受保护字段:

待办事项:使用示例

抽象类 EventListeners 结束

抽象类EventListeners\End实现了Runnable接口,并监听在Lucinda\MVC\Response返回给调用者之后的执行事件。

开发人员需要实现一个run方法,在该方法中,他们可以访问通过构造函数由API注入的以下受保护字段:

START监听器的一个常见示例是需要设置结束时间,以便对处理持续时间进行基准测试。

class EndBenchmark extends Lucinda\ConsoleSTDOUT\EventListeners\End
{
    public function run(): void
    {
        $benchmark = new Benchmark();
        $benchmark->save($this->attributes->getStartTime(), microtime(true));
    }
}

抽象类 控制器

抽象类Controller实现了Runnable接口,通过将先前提到的信息绑定到模型来设置响应(尤其是视图)。它定义了以下与开发人员相关的公共方法

开发人员需要为每个控制器实现run方法,在该方法中,他们可以访问通过API通过构造函数注入的以下受保护字段

待办事项:使用示例

要了解有关控制器检测的更多信息,请查看规范

类属性

Attributes封装了在整个请求-响应周期中收集的数据,每个数据对应一个getter和setter,并可供后续的事件监听器或控制器使用。API已经自带以下功能

大部分收集的数据都需要开发者自己设置以满足项目需求,因此在99%的情况下,每个项目都需要扩展该类!

待办事项:使用示例

规范

由于此API基于抽象MVC API规范,它遵循其要求并增加了额外的要求

如何检测响应格式

本节遵循父API的规范,只是基于$_SERVER["REQUEST_URI"]的值来检测路由。

如何定位视图解析器

本节完全遵循父API的规范

如何检测路由

本节遵循父API的规范,只是路由检测是基于API在控制台请求接收到的第一个参数。

php index.php ROUTE PARAM1 PARAM2 ...

以这个XML为例

<application default_route="index" ...>
	...
</application>
<routes>
    <route id="index" .../>
    <route id="users" .../>
</routes>

对于上面的情况,将出现以下几种情况

如何定位控制器

本节遵循父API的规范,只是作为路由标签中controller属性定义的类必须扩展Controller

如何检测请求参数

用户可以在API请求中发送一个或多个请求参数

php index.php ROUTE PARAM1 PARAM2 ...

然后在控制器/事件监听器中通过以下方式查询这些参数

$parameters = $this->request->parameters();

如果原始请求是

php index.php users hello world

那么路由将是"users",参数将是["hello", "world"]!

如何定位视图

本节完全遵循父API的规范。扩展尚未决定,因为它取决于解析视图的类型!