obsidian-moon / engine
一个开源、轻量级且100%模块化的PHP框架
Requires
- php: >=8.1
- symfony/http-foundation: ^6.2
- symfony/routing: ^6.2
- vlucas/phpdotenv: ^5.5
Requires (Dev)
- roave/security-advisories: dev-latest
README
这是一个我在想要一个完全模块化的框架之后,经过几年工作而完成的项目。我致力于打造轻量级,能够包含来自其他应用程序等任何模块。
安装Obsidian Moon Engine
由于Obsidian Moon Engine使用Composer,您需要先安装它才能使用它运行代码。安装Composer后,您可以运行以下命令进行安装:
composer require obsidian-moon/engine
或者,您可以使用以下命令安装带有预构建结构的Obsidian Moon Framework。点击链接获取更多信息。
composer create-project obsidian-moon/framework
实现
要查看这些功能的完整实现,请查看common.php文件,来自Obsidian Moon Framework。然而,以下是一些扩展的示例,您可以阅读以了解所有可选功能的使用情况。
控制器
控制器是简单的类,其中包含可以从ControllerHandler类调用的方法。您可以扩展内置的抽象类AbstractController,并传递您的视图文件夹配置,如下所示:
// app/Controllers/LandingController.php class LandingController extends AbstractController { /** * Required: Pass the `views` folder configuration to the abstract parent class. * Optional: Pass a set of default values which will be handed off to `ViewHandler` */ public function __construct() { /** * Retrieve default data from database/session or declare statically... */ $optionalDefaultValues = [ 'defaultKey1' => 'defaultValue1', 'defaultKey2' => 'defaultValue2', // ... ]; parent::__construct(viewsRoot: VIEWS_ROOT, viewData: $optionalDefaultValues); } }
控制器处理器
在您的应用程序中,您可以通过symfony/routing或传递一个声明了_controller的数组来传递有关您控制器的信息。当调用ControllerHandler::render()方法并找到声明的类和方法时,它将返回一个Symfony响应。
use ObsidianMoon\Engine\Handlers\ControllerHandler; use ObsidianMoon\Framework\Controllers\LandingController; use ObsidianMoon\Engine\Exceptions\FileNotFoundException; use Symfony\Component\Routing\Exception\MethodNotAllowedException; use Symfony\Component\Routing\Exception\ResourceNotFoundException; /** * Needs an array containing the following keys `_controller` as follows * For Symfony Routing, Replace array with: $matcher->match($request->getPathInfo()) * * Throws FileNotFoundException, Symfony's ResourceNotFoundException, or Symfony's MethodNotAllowedException on error. */ try { $controller = new ControllerHandler(controller: ['_controller' => [LandingController::class, 'index']]); $response = $controller->render(); // Returns Symfony Responce object } catch (FileNotFoundException | ResourceNotFoundException) { // Unable to find that file or route is undefined. $response = 'We could not find that page!'; } catch (MethodNotAllowedException) { // Sent because of unsupported method, e.g. `$_POST` instead of `$_GET`. $response = 'We are unable to process your request. Please try again!'; }
异常处理器
您可以使用自定义异常处理器来处理是否显示错误消息或自定义错误。您可以按照以下方式操作:
use ObsidianMoon\Engine\Exceptions\FileNotFoundException; use ObsidianMoon\Engine\Handlers\ExceptionHandler; /** * Setting `admin` to `false` will return the message we pass to `handle()` method. Otherwise, it will return the * message originally sent from initial exception. */ $exceptions = new ExceptionHandler(admin: false); /** Useful in conjunction with the `ControllerHandler`. */ try { throw new FileNotFoundException('More detailed message for admins'); } catch (FileNotFoundException $e) { $message = $exceptions->handle($e, 'A public error message for non-admins and/or production'); }
视图处理器
视图处理器将查找它被传递的位置,并找到一个声明了该名称的文件,可以返回其值,或将其存储在输出属性中以供以后使用。它可以以多种方式使用,但最常见的方法如下:
use ObsidianMoon\Engine\Exceptions\FileNotFoundException; use ObsidianMoon\Engine\Handlers\ViewHandler; /** Optional default data that can be pulled from DB, session, or static variables to be used in the views. */ $optionalDefaultData = [ 'defaultKey1' => 'defaultValue1', 'defaultKey2' => 'defaultValue2', // ... ]; try { /** Instantiate with VIEWS_ROOT constant set to `src/views` and prepare to make calls */ $view = new ViewHandler(viewsRoot: VIEWS_ROOT, viewData: $optionalDefaultData); /** Load a view `src/views/landing/index.php`, pass it data, and return output to a variable */ $landingContent = $view->load(view: 'landing/index', data: ['key1' => 'value1'], return: true) /** Take the landing content and insert it as a variable into `src/views/layouts/shell.php` */ $view->load(view: 'layouts/shell', data: compact('landingContent')); /** Render the content that has been stored in the handler output. */ $view->render(); } catch (FileNotFoundException $e) { // Did not find the file, handle the 404 here. }
致谢
Obsidian Moon Engine在开发过程中使用了以下库和项目:
- PHP 8与Composer包管理器。
- Symfony 6组件用于HTTP请求和路由。
Obsidian Moon Engine总结
大多数代码旨在尽可能模块化。在1.x版本中,我发现由于路由无法自动处理,我不得不重复大量代码。使用symfony路由组件最终解决了这个问题。然而,我被迫将代码重写得更简单。我希望您觉得这段代码和我一样有用。随着我项目的扩展,我将继续添加更多内容。
此致
Alfonso Martinez
Obsidian Moon开发