mattferris / application
一个 PHP 应用程序加载器
Requires
- mattferris/component: ^1.0
- mattferris/di: ^1.0
- mattferris/events: ~0.4
- mattferris/provider: ~0.3
Requires (Dev)
- phpunit/phpunit: ~4.7
This package is auto-updated.
Last update: 2024-09-18 15:51:33 UTC
README
一个 PHP 应用程序引导框架。
框架基于组件的概念构建。每个组件负责配置自身、注册服务、订阅事件等。这意味着您只需将所需的组件添加到应用程序中并运行它!配置应用程序所需的所有内容只是一个实现了 MattFerris\Di\ContainerInterface
的依赖注入容器(它反过来扩展了 Interop\Container\ContainerInterface
)。
一个简单的 HTTP 应用程序可能看起来像这样
use MattFerris\Application\Application; use MattFerris\Di\Di; // setup your application by adding components to it $app = new Application(new Di(), [ '\MattFerris\Events\EventsComponent', // event handling '\MattFerris\Http\Routing\HttpRoutingComponent' // HTTP request handling ]); // then run it by passing a startup callable to run() $app->run(['\MattFerris\Http\Routing\HttpRoutingComponent', 'run']);
HttpRoutingComponent
有一个名为 run()
的静态方法,它提供了额外的引导以启动请求处理过程。如果您想的话,也可以向 $app->run() 提供自己的 callable
。
组件
组件可能从单个函数到整个库。在应用程序的术语中,一个项目(即代码)只有在项目的配置和初始化被封装成一个整洁的包,并作为实现了 MattFerris\Component\ComponentInterface
的类表示时,才成为组件。通常,这个组件类会位于您项目的顶级命名空间中。
为了简化,您的组件类可以直接扩展 MattFerris\Application\Component
。
namespace My\Project; use MattFerris\Application\Component; class MyProjectComponent extends Component { }
当扩展 MattFerris\Application\Component
时,您将获得一个组件,它将自动加载同一命名空间内的提供者。所以给定的组件,您可以在 My\Project
命名空间内创建提供者。
namespace My\Project; use MattFerris\Provider\ProviderInterface; class EventsProvider implements ProviderInterface { public function provides($consumer) { // register events, etc... } }
此 EventsProvider
现在将在应用程序引导时自动加载。
提供者
组件的唯一真实工作是将在框架中插入提供者。提供者是重载发生的地方,负责将服务注册到服务容器中,将事件监听器注册到事件调度器中,向 HTTP 请求调度器提供路由信息等。提供者必须实现 MattFerris\Provider\ProviderInterface
,该接口要求存在一个名为 provides()
的方法。
默认情况下,没有提供者类型。组件必须在初始化期间注册提供者类型。
// provided by mattferris/bridge-components use MattFerris\Bridge\Components\Di\DiComponent; use MattFerris\Di\Di; use MattFerris\Application\Application; use My\Project\MyProjectComponent; $app = new Application(new Di(), [ DiComponent::class, MyProjectComponent::class ]);
DiComponent
注册一个 Services
提供者类型。您现在可以定义一个 ServicesProvider
来注册服务。
namespace My\Project; use MattFerris\Provider\ProviderInterface; class ServicesProvider implements ProviderInterface { public function provides($consumer) { // $consumer will contain an instance of the service container $container = $consumer; // register a service $container->set('MyProjectService', new MyProjectService()); } }
ServicesProvider::provides()
总是传递配置的服务容器的实例。同样,EventsProvider
将传递事件调度器的实例,依此类推。
提供者类型
到目前为止,我们讨论了 全局 提供者类型。可以通过两种方式在组件中注册 全局 提供者类型。对于扩展 MattFerris\Application\Components
的组件,这就像在组件的类定义中定义 $provides
属性一样简单。
namespace My\Project; use MattFerris\Application\Component; class MyProjectComponent extends Component { protected $providers = [ [ 'MyProjectType' => [ 'consumer' => MyProjectConsumer::class, 'scope' => 'global' ] ] ]; // ... }
消费者 是传递到提供者 provides()
方法的实例类型。在这种情况下,它将是 My\Project\MyProjectConsumer
的实例。因为作用域设置为 global
,组件将自动注册提供者。
对于独立组件(那些不扩展 MattFerris\Application\Component
的组件),提供者类型的注册是通过让组件类实现 MattFerris\Provider\ProviderInterface
并使用 provides()
手动注册类型来完成的。
namespace My\Project; use MattFerris\Component\ComponentInterface; use MattFerris\Provider\ProviderInterface; class MyProjectComponent implements ComponentInterface, ProviderInterface { public function provides($consumer) { // $consumer will contain an instance of MattFerris\Application\Application $consumer->addProvider('MyProjectType', MyProjectConsumer::class); } // ... }
对于扩展 MattFerris\Application\Component
的组件,您还可以为组件的作用域内定义 局部 提供者。这为您提供了隔离组件初始化的灵活性,如所需。
namespace My\Project; use MattFerris\Application\Component; class MyProjectComponent extends Component { protected $providers = [ [ 'MyLocalType' => [ 'consumer' => MyLocalProjectConsumer::class, 'scope' => 'local' ] ] ]; // ... }
高级组件初始化
在某些情况下,组件之间可能存在相互依赖。可以通过定义不同的初始化步骤,使组件能够以这种方式初始化,从而满足这些依赖关系。
use MattFerris\Application\Application; $app = new Application($di, [ [ 'Component\Satisfying\DependenciesComponent' ], // pass 1 [ 'Another\Component\DependingOnFirstComponent' ] // pass 2 ]);
通过简单地传递一个数组数组,可以将组件初始化分解为所需步骤,以成功引导您的应用程序。