simplemvc / skeleton
SimpleMVC框架的骨架应用
Requires
- php: ^7.4 || ^8.0
- league/plates: ^3.4
- monolog/monolog: ^2.8
- php-di/php-di: ^6.0
- simplemvc/framework: ^0.3
Requires (Dev)
- phpstan/phpstan: ^1.7
- phpunit/phpunit: ^9.5
README
这是一个为SimpleMVC框架准备的骨架Web应用。
快速入门
您可以使用以下命令安装骨架应用
composer create-project simplemvc/skeleton
这将创建一个包含基本Web应用的skeleton
文件夹。您可以使用PHP内置的Web服务器执行该应用,如下所示
composer run-script start
应用将在http://localhost:8080执行。
此骨架使用PHP-DI作为DI容器,并使用Plates作为模板引擎。
配置
应用通过(config/config.php)文件进行配置
use App\Config\Route; use Monolog\Logger; use Psr\Container\ContainerInterface; return [ 'routing' => [ 'routes' => Route::getRoutes(), 'cache' => 'data/cache/route.cache' ], 'database' => [ 'pdo_dsn' => 'sqlite:data/db.sqlite', ], 'view' => [ 'path' => 'src/View', 'folders' => [ 'admin' => 'src/View/admin' ], ], 'logger' => [ 'name' => 'app', 'path' => sprintf("data/log/%s.log", date("Y_m_d")), 'level' => Logger::DEBUG, ], // Basic authentication 'authentication' => [ 'username' => 'test', 'password' => '1234567890' ], 'bootstrap' => function(ContainerInterface $c) { session_start(); } ];
每个部分包含路由系统(routing
)、数据库(database
)等的配置。
路由系统
路由系统使用Route类,如下所示(config/Route.php)
class Route { public const LOGIN = '/login'; public const LOGOUT = '/logout'; public const DASHBOARD = '/admin/users'; public static function getRoutes(): array { return [ [ 'GET', '/', Controller\Home::class ], [ 'GET', '/hello[/{name}]', Controller\Hello::class ], [ ['GET', 'POST'], self::LOGIN, Controller\Login::class ], [ 'GET', self::LOGOUT, Controller\Logout::class ], [ 'GET', '/basic-auth', [BasicAuth::class, Controller\Secret::class]], // Admin section [ 'GET', '/admin/users[/{id}]', [Controller\AuthSession::class, Admin\Users\Read::class]], [ 'POST', '/admin/users/{id}', [Controller\AuthSession::class, Admin\Users\Update::class]], [ 'POST', '/admin/users', [Controller\AuthSession::class, Admin\Users\Create::class]], [ 'DELETE', '/admin/users/{id}', [Controller\AuthSession::class, Admin\Users\Delete::class]], ]; } }
此类仅包含一个静态方法,该方法返回路由列表作为数组。路由是数组中的一个元素,包含HTTP方法、URL和要执行的控制器类。URL可以使用FastRoute 语法指定。控制器类也可以使用控制器管道(作为数组)指定。
例如,GET /admin/users[/{id}]
路由有一个包含[Controller\AuthSession, Admin\Users\Read]
的管道。管道中的控制器按顺序执行,即首先执行Controller\AuthSession
,然后是Admin\Users\Read
。
路由缓存
骨架应用的配置允许一个用于路由的缓存文件夹。
return [ 'routing' => [ 'routes' => Route::getRoutes(), 'cache' => 'data/cache/route.cache' ], // ... ]
每次更改路由时,您需要使用以下命令清除缓存
composer run-script clean
如果您想禁用缓存,只需在配置数组中注释(或删除)键即可,如下所示
return [ 'routing' => [ 'routes' => Route::getRoutes(), // 'cache' => 'data/cache/route.cache' ], // ... ]
控制器
SimpleMvc中的每个控制器都实现了ControllerInterface
,如下所示
namespace SimpleMVC\Controller; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; interface ControllerInterface { public function execute(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface; }
execute()
函数接受两个参数,分别是$request
和可选的$response
。这些都是PSR-7 HTTP请求和响应对象。响应通常用于您需要执行多个控制器的管道时,您可能希望将一个控制器的响应传递给另一个控制器。
execute()
函数的返回值是一个PSR-7响应。例如,骨架应用中的Home
控制器如下所示
namespace SimpleMVC\Controller; use League\Plates\Engine; use Nyholm\Psr7\Response; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use SimpleMVC\Controller\ControllerInterface; class Home implements ControllerInterface { protected Engine $plates; public function __construct(Engine $plates) { $this->plates = $plates; } public function execute(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface { return new Response( 200, [], $this->plates->render('home') ); } }
execute()
函数使用nyholm/psr7项目返回一个PSR-7 Nyholm\Psr7\Response
对象。
执行控制器管道
在路由配置文件中,您可以指定要执行的控制器数组。例如,您可以将Secret
控制器指定为需要HTTP认证,并可以在单独的Auth
控制器中实现逻辑。config/route.php
配置中包含了一个示例
use SimpleMVC\Controller; return [ // ... [ 'GET', '/basic-auth', [ BasicAuth::class, Controller\Secret::class ]] ];
数组的第三个元素本身也是一个数组,包含要执行的控制器列表。执行顺序与数组相同,即首先执行BasicAuth
,然后是Secret
。
如果您愿意,您可以通过返回一个HaltResponse对象来停止SimpleMVC的执行流程。这个响应只是一个空的类,它扩展了PSR-7请求,以通知SimpleMVC停止执行。
SimpleMVC提供了一个使用Basic Access Authentication的BasicAuth控制器。
依赖注入容器
所有依赖都使用PHP-DI项目进行管理。
依赖注入容器在config/container.php文件中进行配置。
前端控制器
SimpleMVC应用程序使用public/index.php
文件执行。所有HTTP请求都通过此文件,该文件称为前端控制器。
前端控制器如下所示
use DI\ContainerBuilder; use SimpleMVC\App; use SimpleMVC\Emitter\SapiEmitter; $builder = new ContainerBuilder(); $builder->addDefinitions('config/container.php'); $app = new App($builder->build()); $app->bootstrap(); $request = App::buildRequestFromGlobals(); $response = $app->dispatch($request); SapiEmitter::emit($response);
在这个文件中,我们构建DI容器,从config/container.php文件中读取,并将其注入到SimpleMVC\App类。
应用程序配置存储在DI容器中的config
键中。
我们执行bootstrap
函数。这是一个特殊函数,用于初始化应用程序状态,例如启动PHP会话。
之后,我们使用PHP全局变量$_GET、$_POST、$_SERVER等构建PSR-7 HTTP请求。
然后,我们执行dispatch
函数,根据路由执行Controller(s)。
最后,我们使用SapiEmitter
将PSR-7响应渲染到标准输出。
版权
本软件的作者是Enrico Zimuel和其他贡献者。
本软件根据MIT许可证发布。