nyholm/super-slim

一个快速且可扩展的框架,能够快速交付内容

安装: 27

依赖项: 0

建议者: 0

安全: 0

星标: 38

关注者: 5

分支: 6

开放问题: 0

类型:项目

0.1.0 2019-02-23 14:47 UTC

This package is auto-updated.

Last update: 2024-08-23 02:44:15 UTC


README

你可以开始构建的最快、最好的框架。

composer create-project nyholm/super-slim foobar-microservice

想法

这个框架的想法是为你提供一个良好的基础,以开始构建你的应用程序。在这个框架中,没有文件是神圣的。作为开发者, 对代码和你使用的依赖项负责。

如果你最终超越了这个框架,只需用 Symfony 的 Kernel 替换 Kernel.php,你就可以运行一个 Symfony 4 应用程序。

性能

下表是使用 "hello world" 应用程序进行的比较。

只看 "hello world" 并不能很好地衡量框架的性能。你必须考虑大型应用程序的性能,特别是 你的 大型应用程序的性能。你还必须考虑在框架中开发的速度。

如果你计划构建一个类似于 "hello world" 的小型微服务,上表很有趣。

架构

这个框架相当简单,由不到 5 个类组成。它遵循 Middleware 模式,并支持 Symfony 的 HTTP Foundation。

index.php

前端控制器,其任务是创建一个 Request 并将其传递给 Kernel

Kernel

它从缓存或配置中创建一个容器,然后启动 Runner

Runner

按照在 services.yamlApp\Runner 服务声明中定义的顺序逐个运行中间件链。最后一个中间件应该是调用你控制器的路由器。路由器将返回一个 Response。

当路由器中间件返回响应时,中间件将再次运行,但方向相反。

Router

框架提供了两个路由器:App\Middleware\RouterApp\Middleware\RouterForComplexRoutes。前者仅使用简单的 if-语句来匹配路由与控制器。如果你只有少量路由,这是最快的方法。如果你有更复杂的 preg_match 路由或大量路由,你可能更适合使用 RouterForComplexRoutes。它使用 Symfony 4 路由器,这是用 PHP 编写的最快的通用路由器。

确保你对你的应用程序进行性能分析,以查看哪个路由器更适合你。

Controller

这里是你正常的 PHP 类和代码。你的控制器应该始终返回一个 Response。

服务

你可以创建任意多的服务、值对象、数据库实体。你可以使用 config/services.yaml 来注册你的服务。默认情况下,它们将与 Symfony 依赖注入 容器自动绑定。

配置

配置应用程序很简单。你可以使用环境变量或 .env 文件进行特定于主机的配置。如果你想要注册服务或修改行为,请检查 config/ 文件夹。

如果你熟悉 Symfony 配置,那么配置 SuperSlim 不会有任何问题。

数据库

你的应用程序可能需要使用数据库。只需选择你喜欢的数据库连接方式,并将其注册为服务。这里是一个使用 Doctrine 的示例。

composer require doctrine/orm
# config/packages/doctrine.yaml

services:
  doctrine.config:
    class: Doctrine\ORM\Configuration
    factory: Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration
    arguments:
      - ['%kernel.project_dir%/src']
      - 'kernel.debug'
      - null
      - null
      - false

  Doctrine\ORM\EntityManagerInterface:
    factory: Doctrine\ORM\EntityManager::create
    arguments:
      - { driver: pdo_mysql, url: '%env(resolve:DATABASE_URL)%' }
      - '@doctrine.config'

  doctrine.console_helper:
    class: Symfony\Component\Console\Helper\HelperSet
    public: true
    factory: Doctrine\ORM\Tools\Console\ConsoleRunner::createHelperSet
    arguments: ['@Doctrine\ORM\EntityManagerInterface']
# .env.local

DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity()
 * @ORM\Table(name="products")
 */
class Product
{
    /**
     * @ORM\Id()
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue()
     */
    protected $id;

    /**
     * @ORM\Column(type="string")
     */
    protected $name;

    public function getId()
    {
        return $this->id;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setName($name)
    {
        $this->name = $name;
    }
}

如果你想要启用 CLI 支持

// cli-config.php

use App\Kernel;

require __DIR__.'/config/bootstrap.php';

$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
$kernel->boot();

return $kernel->getContainer()->get('doctrine.console_helper');
vendor/bin/doctrine orm:schema-tool:update --force --dump-sql

模板化

返回 new Response('Hello world'); 并不是很有趣。你可能想使用一些模板。选择你喜欢的工具,并将其注册为服务。这里是一个使用 Twig 的示例。

composer require twig/twig
# config/packages/twig.yaml

services:
  Twig\Loader\FilesystemLoader:
    arguments: ['%kernel.project_dir%/templates']

  Twig\Environment:
    arguments:
      - '@Twig\Loader\FilesystemLoader'
      - { cache: '%kernel.cache_dir%/templates' }
namespace App\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Twig\Environment;

class MyTwigController
{
    private $twig;

    public function __construct(Environment $twig)
    {
        $this->twig = $twig;
    }

    public function index()
    {
        return new Response($this->twig->render('index.html.twig', ['name' => 'Foobar']));
    }
}
{# templates/index.html.twig #}

Hello {{ name }}!

缓存

既然你正在构建一个小型且超快的应用程序,那么缓存可能对你来说非常重要。选择你喜欢的缓存库,并将其注册为服务。这里是一个使用 Symfony 缓存 的示例。

composer require symfony/cache
# config/packages/symfony_cache.yaml

services:
  symfony.cache.memcached:
    class: Symfony\Component\Cache\Adapter\MemcachedAdapter
    arguments: ['@native.memcached']

  native.memcached:
    class: Memcached
    factory: Symfony\Component\Cache\Adapter\MemcachedAdapter::createConnection
    arguments:
        - '%env(resolve:CACHE_URL)%'
        - { 'persistent_id': 'super_slim' }

CacheInterface 配置一个别名以在生产中使用 Memcached。

# config/services.yaml

services:
    Symfony\Contracts\Cache\CacheInterface: '@symfony.cache.memcached'

在开发中,我们希望使用 Void 缓存。

# config/services_dev.yaml

services:
  Symfony\Contracts\Cache\CacheInterface: '@App\Service\VoidCache'
# .env.local

CACHE_URL=memcached://localhost

然后使用内置的 App\Middleware\Cache 来缓存每个 URL。你可以自由改进这个类中缓存键的创建和其他逻辑。

namespace App\Middleware;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;

class Cache implements MiddlewareInterface
{
    private $cache;

    public function __construct(CacheInterface $cache)
    {
        $this->cache = $cache;
    }

    public function __invoke(Request $request, RequestHandlerInterface $handler): Response
    {
        $cacheKey = sha1($request->getUri());

        return $this->cache->get($cacheKey, function (ItemInterface $item) use ($handler, $request) {
            $item->expiresAfter(3600);

            return $handler->handle($request);
        });
    }
}

这个框架的未来

显然,这个小项目并不是任何大型框架的竞争对手,它永远不应该被当作那样对待。它只是一个练习,展示基于 Symfony 组件构建小型应用程序有多简单。如果有人使用类似 SuperSlim 的架构,在将来需要升级到完整的 Symfony 框架时,将不会遇到任何问题。

我会把它当作一个兴趣爱好项目。如果你喜欢它,给它一个星标,并复制它来将其变成你喜欢的东西。

或者,你可以阅读这些优秀的文章,并 构建你自己的框架