totallyquiche / crudy
一个MVC框架的示例。
Requires
- php: >=8.1
README
CRUDy是一个无依赖的PHP框架示例。
但是为什么?
为了好玩,当然是!毕竟,学习是基础!🌈
CRUDy正在帮助我磨练我的PHP技能,并更深入地了解构建在流行的PHP框架之上的概念。
CRUDy 不应该在生产环境中使用。CRUDy的开发从天真方法开始,而不是从现有标准(例如PSR)开始。我随着时间的推移开发这些实现,因为我学会了不同模式的优势和劣势。兼容性、性能,甚至安全性都不是重点,也不保证。
欢迎反馈!如果你愿意,甚至可以发起一个Pull Request。:smile
功能
- 自动加载
- 页面缓存
- 环境变量 (.env)
- 数据库抽象层 (DBAL)
- 无头执行
- MVC架构
- 路由
- 模板
- 测试
入门
- 克隆仓库:
git clone git@github.com:totallyquiche/CRUDy.git - 创建你的配置文件:
cp .env.example .env - 启动你的PHP服务器:
php -S localhost:80 - 在浏览器中打开
https://
技术上,就是这样!CRUDy已经启动并运行!但你可能想做更多...
创建新页面
在 ./App/Http/routes.php 中的 $routes 数组中添加新路由。你可以指定控制器和方法,或者一个匿名函数。你定义的方法/函数应该返回一个字符串(这就是要渲染的内容)。
$routes = [ '/' => 'HomeController::index' ];
$routes = [ '/' => fn() => 'Hello, World!' );
创建控制器
在 App/Controllers/Http 中创建一个新的类,该类扩展了 App\Http\Controllers\HttpController。类名应该以 Controller 结尾(例如 HomeController)。文件名应该是类名加上 .php(例如 HomeController.php)。
控制器应包含与任何已注册路由匹配的方法。例如,如果我已注册了一个引用 HomeController::index 的路由,那么我应该有一个名为 HomeController 的控制器,其中有一个名为 index() 的方法,该方法返回一个字符串。
创建视图
在 App/View/Templates 中创建一个新的 .php 文件。通过在控制器方法中调用 $this->renderView($view_name, $args) 来从控制器中加载视图。
第一个参数是视图的名称(不带 .php)。第二个参数是传递给视图的可选数组数据。数组中的键/值对被转换为具有分配值的变量。
例如,调用以下方法将导致加载 show_object 视图(App/View/Templates/show_object.php)。视图将有一个名为 $object_name 的变量,其值为 Object Name;
$this->renderView('show_object', [ 'object_name' => 'Object Name'; ]);
$args 中的值也可以是 Callable。例如,调用以下方法将给视图访问名为 $message 的变量的权限,其值为 Hello, World!
$this->renderView('view_name', [ 'message' => fn() => return 'Hello, World!', ]);
模板
模板可以用于支持一种类型的单继承视图,其中模板中的 {{ 💩 }} 字符串被替换为视图的内容。
使用模板
要使用模板,请确保你的视图文件的第一行包含类似 {{ TEMPLATE_NAME }} 的字符串,其中 TEMPLATE_NAME 是模板的文件名,不带 .php。例如,以下视图将使用位于 App\View\Templates\page.php 的模板。
{{ page }}
<h1>Hello, World!</h1>
创建模板
模板是文件,其名称符合 [a-zA-Z]+\.php(例如 page.php),并位于 App\View\Templates。它们应包含一个占位符 {{ 💩 }},用于在它们中嵌入视图。例如
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title><?= $site_title ?></title> </head> <body> {{ 💩 }} </body> </html>
具有以下视图...
{{ page }}
<h1>Hello, World!</h1>
...结果如下所示
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title><?= $site_title ?></title> </head> <body> <h1>Hello, World!</h1> </body> </html>
视图缓存
视图完全编译后,会被写入位于 ./App/View/Templates/Cache 的缓存中。每当请求相应的页面时,都会使用这个缓存文件,直到缓存期结束(由环境变量 VIEW_CACHE_SECONDS_TO_EXPIRY 设置的秒数)。
测试
编写测试
在 ./App/Tests 中创建一个新的类,该类继承自 App\Tests\Test。类名应以 Test 结尾(例如 HomeControllerTest)。文件名应该是类名加上 .php(例如 HomeControllerTest.php)。
你的测试方法应该是 public 的,应该以 test_ 开头,并且应该返回一个 boolean 值,指示测试是否通过。
public function test_that_true_is_true() : bool { return true === true; }
运行测试
只要遵循上述命名约定,你的测试将通过以下命令自动运行
php index.php tests:run
你可以通过传递它们的名称作为参数来运行特定的测试
php index.php tests:run "App\Tests\ModelTest" "App\Tests\RouterTest"
测试结果
运行你的测试后,你将看到结果打印到屏幕上。
每个测试案例将以 通过 或 失败 开头显示。总通过/失败计数将在最后显示。

