nyholm / super-slim
一个快速且可扩展的框架,能够快速交付内容
Requires
- php: ^7.2
- psr/cache: ^1.0
- symfony/config: ^4.2
- symfony/dependency-injection: ^4.2
- symfony/flex: ^1.2
- symfony/http-foundation: ^4.2
- symfony/yaml: ^4.2
Requires (Dev)
- symfony/dotenv: ^4.2
- symfony/routing: ^4.2
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.yaml
中 App\Runner
服务声明中定义的顺序逐个运行中间件链。最后一个中间件应该是调用你控制器的路由器。路由器将返回一个 Response。
当路由器中间件返回响应时,中间件将再次运行,但方向相反。
Router
框架提供了两个路由器:App\Middleware\Router
和 App\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 框架时,将不会遇到任何问题。
我会把它当作一个兴趣爱好项目。如果你喜欢它,给它一个星标,并复制它来将其变成你喜欢的东西。
或者,你可以阅读这些优秀的文章,并 构建你自己的框架。