thumbsupcat / iced-americano
用 PHP 编写的微框架
This package is auto-updated.
Last update: 2024-09-14 11:50:49 UTC
README
用 PHP 编写的用于 Web 服务的微框架
目的
用 PHP 编写提供路由、会话、数据库等功能的 Web 框架。
目标
- 路由:从 HTTP 请求中提取方法、路径。可以注册和执行处理器和中间件。
- 数据库:使用 PDO,以 MySQL 为基础。
- 会话:可以使用数据库来管理会话。
- 主题:可以选择 HTML 模板并传递变量以向用户显示页面,类似于模板引擎。
- 模块化:基于用户提供的模块,Web 服务运行。
实现后思考
这个项目是在听 Inflearn 课程 的同时进行的。我尽量避免机械地输入代码,但与其说是我自己主导,不如说是跟着课程的方向前进。项目完成后,我用 Laravel 开发了另一个 项目。使用 Laravel 后,我发现它与这个项目在很多方面都很相似。当然,Laravel 方面要大得多,也复杂得多,但结构相似。而且,这个项目非常忠实于这种结构和趋势。因此,我决定一个个仔细研究。
该项目中存在一个名为 RequestContext 的类。这是用于注册路由的对象。请求包含的上下文是什么?那将是方法、URI、处理器。如果将处理器细分,则可以分为路由专用处理器和通用中间件。因此,RequestContext 成为一个包含方法、URI、处理器、中间件的容器,它具有用户请求的上下文。这个对象看起来是被动性的。因为它是被路由注册和执行的,所以服务器在接收和处理请求的过程中,RequestContext 看起来就像一个被动对象。
然而,从面向对象的角度来看,每个对象都是主动的。因此,路由可以将请求分配给适当的需求上下文,但需求上下文也可以选择检查这个请求是否适合自己。在这个项目中,我们选择了后者。路由只是将需求上下文包含起来执行,而请求是否合适、是否将参数传递给已注册的处理器等,则由需求上下文负责。需求上下文不是包含上下文数据的简单数据块,而是作为一个对象执行。
看起来被动的对象实现是主动的,这很符合代码,代码的执行也更加流畅。因此,我想更多地了解面向对象。我读了一本名为 面向对象的事实与误解 的书。因此,我将我的结论整理在 链接 中。
实现内容
整体执行流程
从客户端请求的入口点(index.php)接收请求并执行 Application。Application 是框架中提供的类,其中包含 ServiceProvider。ServiceProdiver 是包含用户想要提供给 Web 服务的功能的类。从路由、会话管理到时区设置等所有操作都定义在其中。Application 将按顺序执行注册的 ServiceProvider,并向客户端响应。
目录结构
src
│ Application.php
│
├─Database
│ Adaptor.php
│
├─Http
│ Request.php
│
├─Routing
│ Middleware.php
│ RequestContext.php
│ Route.php
│
├─Session
│ DatabaseSessionHandler.php
│
└─Support
ServiceProvider.php
Theme.php
详细信息
路由
- 目录:Routing
- 文件:Route.php, RequestContext.php, Middleware.php
- 路由定义了对 HTTP 请求的响应。有定义了 HTTP 方法、路径、响应操作的处理器。
- 路径有如 '/post' 这样的静态路径和如 '/post/{id}' 这样的动态路径,因此需要相应的处理。
Middleware
定义了可以在多个路由中使用的通用处理器。有用于响应的主处理器,以及在此之前调用的中间件。RequestContext
是用于管理路由所需材料的单元。match
方法接收要比较的 URL 作为参数,并检查当前RequestContext
是否处理当前的请求。如果匹配成功,则返回动态路径中的数据。runMiddleware
方法执行所有注册的中间件。
Route
负责路由。使用RequestContext
注册和执行路由。run
方法比较 HTTP 请求信息和注册的路由,并执行。- 检查 get、post、delete 等 HTTP 方法和路径,提取与动态路径相对应的数据,并调用处理器。
HTTP 请求
- 目录:Http
- 文件:Request.php
- 分析传入的 HTTP 请求并提取方法、路径等功能。
数据库
- 目录:Database
- 文件:Adaptor.php
- 在内部使用PDO访问数据库。通过使用预编译语句来防止SQL注入。
- 可以使用
exec
方法处理CRUD操作。 - 使用
getAll
方法从表中获取数据。通过指定类,可以以该类的实例接收数据。
会话
- 目录:Session
- 文件:DatabaseSessionHandler.php
- 通过继承PHP为会话提供的SessionHandlerInterface来构建类。
- 内部使用
Adaptor
类。 - 会话中保存的数据与数据库连接并管理。
主题
- 目录:Support
- 文件:Theme.php
- 结构化以允许使用预先编写的布局,就像模板引擎一样。
view
方法中使用变量变量(使用$$)来将字符串作为变量名进行替换,以便可以使用传递的关联数组的键作为布局的变量名。setLayout
方法负责调用一次,并负责整个布局(头部、导航、主要内容、页脚)。在view
方法中变化的是主要内容。
ServiceProvider
- 目录:Support
- 文件:ServiceProvider.php
- ServiceProvider提供了一个框架,允许用户注册服务(服务器运行期间要执行的逻辑)。
- ServiceProvider提供了错误处理、会话管理、数据库控制、路由、主题等功能,提供给Application。
- 最初是一个抽象类,但由于内部没有操作,所以已将其更改为接口。
Application
- 目录:根目录(src目录)
- 文件:Application.php
- Application负责接收ServiceProvider并执行。
- 路由、会话管理等所有逻辑都必须由用户定义并注册到Application中,使用ServiceProvider。
参考
此代码基于PHP 7+ 编程:面向对象课程编写。