nyholm / sunflower
简单应用的最佳内核。
Requires
- php: >=7.4
- symfony/config: ^5.3 || ^6.0
- symfony/dependency-injection: ^5.3 || ^6.0
Requires (Dev)
- happyr/service-mocking: ^0.2.0
- phpunit/phpunit: ^9.5
- symfony/http-kernel: ^5.3 || ^6.0
- symfony/yaml: ^5.3
README
Sunflower是一个超小的应用内核,用于构建依赖注入容器。这个内核对于不使用HTTP的微服务和应用程序很有用。比如:从队列中读取或由AWS Lambda调用的应用程序。
使用这个内核,您可以使用带有自动装配的正常Symfony服务定义,甚至支持Symfony扩展包!
与使用symfony/http-kernel
和Symfony FrameworkBundle相比,Sunflower不使用symfony/event-dispatcher
、symfony/console
、symfony/security
、symfony/cache
和symfony/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实际上为您做了什么。经过一些私有迭代和更多应用程序的创建,我们最终去除了所有不必要的功能,最终只剩下一个内核。