lastzero/symlex-core

基于Symfony组件的简约内核和路由器

v4.4.1 2022-07-05 07:13 UTC

README

Latest Stable Version License Test Coverage Build Status Documentation Community Chat

注意:此存储库包含内核和路由器作为可重用组件。有关更多信息以及基于symlex-core的完整框架,请参阅https://github.com/symlex/symlex

如phpbenchmarks.com发布所示,Symlex比其他常见的PHP框架为REST请求添加了显著更少的开销

我们的完整框架文档可以在docs.symlex.org找到。 Tuzi Liu为我们维护了一个中文翻译

内核

轻量级的Symlex内核可以启动几乎任何应用程序。它基于我们的di-microkernel库。内核本身只需几行代码来设置环境参数,初始化Symfony服务容器,然后通过调用run()来启动应用程序。

位于config/目录下的YAML文件配置应用程序及其所有依赖项作为服务。文件名与应用程序的环境名称匹配(例如,config/console.yml)。配置还可以通过提供匹配的配置文件(例如,config/console.local.yml)来修改子环境(例如,本地或生产环境)的配置(请参阅app.sub_environment参数)。这些文件采用与您可能从Symfony中了解的相同的良好文档格式。

parameters:
    app.name: 'My App'
    app.version: '1.0'

services:
    doctrine.migrations.migrate:
        class: Doctrine\DBAL\Migrations\Tools\Console\Command\MigrateCommand
        
    app:
        class: Symfony\Component\Console\Application
        arguments: [%app.name%, %app.version%]
        public: true
        calls:
            - [ add, [ "@doctrine.migrations.migrate" ] ]

这为使用相同的内核启动Web应用程序(如Symlex\Application\Web)或命令行应用程序(如Symfony\Component\Console\Application,在Symlex\Application\Console中包装)提供了一种统一的方法。结果比许多框架中常见的启动和配置混乱更加整洁和精简。

禁用缓存

如果关闭了调试模式,内核将在设置为缓存路径的目录中缓存服务容器配置。在更新配置后,您必须删除所有缓存文件。要完全禁用缓存,请在配置参数中添加container.cache: false

parameters:
    container.cache: false

路由器

此库包含三个路由器类。它们配置Symfony路由器组件以执行实际的路由,因此您可以期望相同的高性能。在将请求路由到适当的控制器操作后,路由器随后将响应渲染出来以简化控制器测试(操作从不直接返回JSON或HTML)。

  • Symlex\Router\Web\RestRouter处理REST请求(JSON)
  • Symlex\Router\Web\ErrorRouter将异常渲染为错误消息(HTML或JSON)
  • Symlex\Router\Web\TwigRouter通过Twig渲染常规Web页面(HTML)
  • Symlex\Router\Web\TwigDefaultRouter类似于TwigRouter,但它将所有请求发送到默认控制器操作(对于客户端路由例如Vue.js是必需的)

根据现有示例,可以轻松创建自己的自定义路由/渲染。

应用程序的HTTP内核类初始化在服务容器中配置的路由器。

<?php

namespace Symlex\Kernel;

class WebApp extends App
{
    protected $urlPrefix = '';

    public function __construct($appPath, $debug = false)
    {
        parent::__construct('web', $appPath, $debug);
    }

    public function init()
    {
        if ($this->debug) {
            ini_set('display_errors', 1);
        }
    }

    public function getUrlPrefix($urlPrefixPostfix = ''): string
    {
        return $this->urlPrefix . $urlPrefixPostfix;
    }

    public function setUrlPrefix(string $urlPrefix)
    {
        $this->urlPrefix = $urlPrefix;
    }

    protected function setUp()
    {
        $container = $this->getContainer();

        // The error router catches errors and displays them as error pages
        $container->get('router.error')->route();

        // Routing for REST API calls
        $container->get('router.rest')->route($this->getUrlPrefix('/api'), 'controller.rest.');

        // All other requests are routed to matching controller actions
        $container->get('router.twig')->route($this->getUrlPrefix(), 'controller.web.');
    }
}

REST和Twig路由器接受可选的URL前缀(例如/api)和服务名称前缀(例如controller.rest.)。

默认HTTP内核(Symlex\Kernel\WebApp)的路由示例

  • GET /将路由到controller.web.index服务的indexAction(Request $request)
  • POST /session/login将路由到controller.web.session服务的postLoginAction(Request $request)
  • GET /api/users将路由到controller.rest.users服务的cgetAction(Request $request)
  • POST /api/users将路由到controller.rest.users服务的postAction(Request $request)
  • OPTIONS /api/users将路由到controller.rest.users服务的coptionsAction(Request $request)
  • GET /api/users/123将路由到controller.rest.users服务的getAction($id, Request $request)
  • OPTIONS /api/users/123将路由到controller.rest.users服务的optionsAction($id, Request $request)
  • GET /api/users/123/comments将路由到controller.rest.users服务的cgetCommentsAction($id, Request $request)
  • GET /api/users/123/comments/5将路由到controller.rest.users服务的getCommentsAction($id, $commendId, Request $request)
  • PUT /api/users/123/comments/5将路由到controller.rest.users服务的putCommentsAction($id, $commendId, Request $request)

路由器将请求实例传递给每个匹配的控制器操作作为最后一个参数。它包含请求参数和头信息:[https://symfony.com.cn/doc/current/book/http_fundamentals.html#requests-and-responses-in-symfony](https://symfony.com.cn/doc/current/book/http_fundamentals.html#requests-and-responses-in-symfony)

TwigRouter调用的控制器操作可以返回空(将渲染匹配的Twig模板),一个数组(Twig模板可以访问这些值作为变量)或一个字符串(重定向URL)。

REST控制器操作(由RestRouter调用)始终返回数组,这些数组将被自动转换为有效的JSON。删除操作可以返回null("204 No Content")。

拦截器

HTTP拦截器可以用于在路由请求之前执行HTTP身份验证或其他操作(例如,阻止某些IP地址范围)。

<?php

use Symlex\Kernel\App;

class WebApp extends App
{
    public function __construct($appPath, $debug = false)
    {
        parent::__construct('web', $appPath, $debug);
    }

    public function boot () {
        parent::boot();

        $container = $this->getContainer();

        /*
         * In app/config/web.yml:
         *
         * services:
         *     http.interceptor:
         *         class: Symlex\Router\HttpInterceptor
         */
        $interceptor = $container->get('http.interceptor');
        $interceptor->digestAuth('Realm', array('foouser' => 'somepassword'));

        $container->get('router.error')->route();
        $container->get('router.rest')->route('/api', 'controller.rest.');
        $container->get('router.twig')->route('', 'controller.web.');
    }
}

通过Symlex\Kernel\WebApps运行多个内核

注意:这是一个实验性的概念验证。欢迎反馈。

作为Symfony扩展的替代,Symlex\Kernel\WebApps可以在同一个Symlex安装上运行多个基于Symlex\Kernel\App的应用程序。

$app = new WebApps('web', __DIR__ . '/../app', false);
$app->run();

它像普通的WebApp一样启动,然后根据app/config/web.guests.yml中的配置启动其他Symlex应用程序(路径、调试、前缀和域名是可选的;启动和配置是必需的)。

example:
    prefix: /example
    domain: www.example.com
    bootstrap: \Symlex\Kernel\WebApp
    config: web.yml
    debug: true
    path: vendors/foo/bar/app

default:
    bootstrap: \Symlex\Kernel\WebApp
    config: web.default.yml

注意:与Assetic在Symfony扩展中所做的方式不同,web/中的资产(例如图像、CSS或JavaScript)不会自动共享。如果您的应用程序不仅提供Web服务,您可能需要创建符号链接或修改您的HTML模板。

关于

Symlex由Michael Mayer维护,旨在通过提供一个促进最佳实践的示例系统来简化敏捷Web开发。Michael于2001年发布了他的第一个PHP框架,之前曾与主要框架供应商合作。如果没有其他开发者的大量前期工作,这是不可能实现的。感谢他们以及所有贡献者!

如果您有任何问题,需要商业支持或只是想打个招呼,请随时发送电子邮件到hello@symlex.org。欢迎贡献,即使只是微小的pull-request或错误报告。

捐赠

如果您喜欢这个项目,请留下一个星标,这将为继续前进提供足够的动力。非常感谢!<3