lucinda / console-mvc
适用于PHP应用的MVC模式,通过MVC模式处理控制台请求到响应的超高性能API
Requires
- php: ^8.1
- ext-simplexml: *
- lucinda/abstract_mvc: ^2.0
Requires (Dev)
- lucinda/unit-testing: ^2.0
This package is auto-updated.
Last update: 2024-09-12 01:00:33 UTC
README
目录
关于
此API是一个 骨架(需要开发者绑定),用于高效地处理控制台请求到服务器响应,使用MVC版本,其中视图和模型应相互独立,而控制器根据用户请求在两者之间进行调解。以模块化、效率和简洁为基础设计,API是对象和事件导向的:类似于JavaScript,它允许开发者在处理过程中绑定在预定义事件达到时执行的逻辑。
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!
处理
完成上述步骤后,开发人员最终可以通过FrontController的run方法处理请求到响应,该方法
- 检测EventListeners\Start监听器并按注册顺序执行它们
- 将配置XML文件封装到Lucinda\MVC\Application对象中
- 检测EventListeners\Application监听器并按注册顺序执行它们
- 将请求信息(环境信息、机器信息、请求信息)封装到Request对象中
- 检测EventListeners\Request监听器并按注册顺序执行它们
- 根据从请求或XML中检测到的信息初始化空的Lucinda\MVC\Response
- 根据已经检测到的信息定位Controller,如果找到,则按顺序执行以将模型绑定到视图
- 根据已经检测到的信息定位Lucinda\MVC\ViewResolver并按顺序执行,以根据视图填充响应体
- 检测并按注册顺序执行EventListeners\Response监听器
- 将Lucinda\MVC\Response发送回调用者,包含头信息和主体
- 检测并按注册顺序执行EventListeners\End监听器
所有由开发者负责的组件(Controller、Lucinda\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\UserInfo:封装关于发起请求的console用户的信息
除了在绑定事件中提到的类之外,以下抽象类需要由开发者扩展,以获得能力
- Controller:根据用户请求和XML信息封装绑定Request到Lucinda\MVC\Response
类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的规范。扩展尚未决定,因为它取决于解析视图的类型!