nyholm/sunflower

简单应用的最佳内核。

资助包维护!
Nyholm

0.2.1 2021-09-05 02:36 UTC

This package is auto-updated.

Last update: 2024-09-14 14:45:15 UTC


README

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

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

与使用symfony/http-kernel和Symfony FrameworkBundle相比,Sunflower不使用symfony/event-dispatchersymfony/consolesymfony/securitysymfony/cachesymfony/router

性能

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

使用“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和简单切换路由器的简短示例。此示例使用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实际上为您做了什么。经过一些私有迭代和更多应用程序的创建,我们最终去除了所有不必要的功能,最终只剩下一个内核。