nyholm/nano-kernel

该软件包已被废弃,不再维护。作者建议使用 nyholm/sunflower 软件包。

简单应用的最佳内核。

资助软件包维护!
Nyholm

0.2.1 2021-09-05 02:36 UTC

This package is auto-updated.

Last update: 2022-08-14 09:41:11 UTC


README

Sunflower 是一个超级小巧的应用程序内核,用于构建依赖注入容器。这个内核对于不使用 HTTP 的微服务和应用很有用。例如;从队列读取或由 AWS Lambda 触发的应用。

使用这个内核,您可以使用带有自动装配等常规 Symfony 服务定义。它甚至支持 Symfony 扩展!

与使用 symfony/http-kernel 和 Symfony FrameworkBundle 的主要区别在于,Sunflower 不使用 symfony/event-dispatchersymfony/consolesymfony/securitysymfony/cachesymfony/router

性能

以下表格展示了使用不同框架的 "hello world" 应用程序每秒请求数。具体的数字并不重要,它们取决于测试运行的机器。但应该考虑不同框架之间数字的变化,因为所有测试都是在同一台机器上运行的。

框架 Req/s
Sunflower 2.548
Symfony 6.0 1.819
Symfony 5.4 1.804
Slim 4 1.380
Mezzio 3 985
Laravel 8 421

使用 "hello world" 进行比较有一些缺点。它确实展示了只有几百行代码的小型应用的性能,但它并不能说明大型应用的性能。它也不会告诉你编写和维护应用的速度。

上述表格如果您计划构建类似于 "hello world" 的小型微服务,那么是非常有趣的。如果您熟悉 Symfony 的依赖注入、配置和第三方扩展,使用 Sunflower 内核也是非常有趣的。

安装

composer require nyholm/sunflower

使用

// src/Kernel.php
namespace App;

use Nyholm\SunflowerKernel;

class Kernel extends SunflowerKernel
{
   /**
    * Optionally override the configureContainer()
    */
   protected function configureContainer(ContainerConfigurator $container): void
    {
        $container->import('../config/{packages}/*.yaml');
        $container->import('../config/{packages}/'.$this->environment.'/*.yaml');
        $container->import('../config/{packages}/'.$this->environment.'/*.php');

        if (\is_file(\dirname(__DIR__).'/config/services.yaml')) {
            $container->import('../config/services.yaml');
            $container->import('../config/{services}_'.$this->environment.'.yaml');
        } else {
            $container->import('../config/{services}.php');
        }
    }
}
use App\Kernel;
use App\Service\MyService;

require_once dirname(__DIR__).'/vendor/autoload.php';

$kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
$kernel->getContainer()->get(MyService::class)->run();

与 HTTP 一起使用

这是一个使用 HTTP 和简单的 switch-router 的简短示例。此示例使用 runtime/psr-nyholm

// public/index.php

use Nyholm\Psr7;

require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

return function (array $context) {
    $kernel = new \App\Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
    $container = $kernel->getContainer();

    // This is an example router
    $urlPath = $context['REQUEST_URI'];
    switch ($urlPath) {
        case '/':
        case '':
            // This is an RequestHandlerInterface
            return $container->get(\App\Controller\Startpage::class);
        case '/foobar':
            return $container->get(\App\Controller\Foobar::class);
        default:
            return new Psr7\Response(404, [], 'The route does not exist');
    }
};
# config/services.yaml

services:
    _defaults:
        autowire: true
        autoconfigure: true

    _instanceof:
        Psr\Http\Server\RequestHandlerInterface:
            public: true

    App\:
        resource: '../src/'
        exclude:
            - '../src/Kernel.php'

与 Bref 一起使用

要创建与 Bref 兼容的应用,您需要 runtime/bref 软件包。创建微服务、SQS 读取器或响应 S3 事件等。

// src/Kernel.php

namespace App;

use Nyholm\SunflowerKernel;

class Kernel extends SunflowerKernel
{
    public function isLambda(): bool
    {
        return false !== \getenv('LAMBDA_TASK_ROOT');
    }

    public function getCacheDir(): string
    {
        if ($this->isLambda()) {
            return '/tmp/cache/'.$this->environment;
        }

        return parent::getCacheDir();
    }

    public function getLogDir(): string
    {
        if ($this->isLambda()) {
            return '/tmp/log/';
        }

        return parent::getLogDir();
    }

    public function getProjectDir(): string
    {
        return \dirname(__DIR__);
    }
}
// bin/container.php

use App\Kernel;

require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

return function (array $context) {
    $kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);

    return $kernel->getContainer();
};
# config/services.yaml

services:
    _defaults:
        autowire: true
        autoconfigure: true

    _instanceof:
        Bref\Event\Handler:
            public: true

    App\:
        resource: '../src/'
        exclude:
            - '../src/Kernel.php'
 # serverless.yml

  functions:
      app:
          handler: bin/container.php:App\Service\MyHandler

与 CLI 一起使用

// bin/console
#!/usr/bin/env php
<?php

use App\Kernel;
use Symfony\Component\Console\Application;

require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

return function (array $context) {
    $kernel = new Kernel($context['APP_ENV'], (bool)$context['APP_DEBUG']);
    $container = $kernel->getContainer();

    $app = new Application();
    // Register all your commands here
    $app->add($container->get(\App\Command\HelloCommand::class));

    return $app;
};
declare(strict_types=1);

namespace App\Command;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand(name: 'app:debug:hello')]
class HelloCommand extends Command
{
    protected function configure()
    {
        $this->setDescription('Test print hello.');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $output->writeln('Hello');

        return Command::SUCCESS;
    }
}
# config/services.yaml

services:
    _defaults:
        autowire: true
        autoconfigure: true

    _instanceof:
        Symfony\Component\Console\Command\Command:
            public: true

    App\:
        resource: '../src/'
        exclude:
            - '../src/Kernel.php'

历史

Sunflower 项目于 2021 年开源。项目的第一个版本是在 2015 年创建的。围绕使用 Symfony 的依赖注入组件但不使用 FrameworkBundle 或 HttpKernel 的概念创建了一些私有应用。

项目的第一个公开版本是SuperSlim。那个版本是一个具有偏见的框架,用于展示FrameworkBundle实际上在幕后为你做了什么。经过一些私有迭代和创建了许多应用程序之后,我们最终去除了所有不必要的部分,最终只留下了一个Kernel。