| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
The Kernel component of the Snicco project helps to bootstrap an application that uses a plugin architecture.
composer require snicco/kernelThe Kernel class helps to load and cache configuration files, define services in a dependency-injection container and bootstrap an application in a controlled manner using any number of bootstrappers and bundles.
A bootstrapper can be any class that implements the Bootstrapper interface:
A bootstrapper is a class responsible for "bootstrapping" one cohesive part of an application.
"Bootstrapping" could mean, for example: registering definitions in a dependency injection container or creating event listeners.
Bootstrappers are the central place to configure the application.
interface Bootstrapper
{
public function shouldRun(Environment $env): bool;
public function configure(WritableConfig $config, Kernel $kernel): void;
public function register(Kernel $kernel): void;
public function bootstrap(Kernel $kernel): void;
}A bundle can be any class that implements the Bundle interface. The Bundle interface extends the Bootstrapper interface.
interface Bundle extends Bootstrapper
{
public function alias(): string;
}The difference between a bundle and a bootstrapper is that a bundle is meant to be publicly distributed, while a bootstrapper is internal to a specific application.
Bundles are aware of other bundles that are used by the same Kernel instance.
A Kernel always needs an environment to run in.
The following environments are possible:
use Snicco\Component\Kernel\ValueObject\Environment;
$environment = Environment::prod()
$environment = Environment::testing()
$environment = Environment::staging()
$environment = Environment::dev()
$environment = Environment::fromString(getenv('APP_ENV'));A Kernel always needs a Directories value object that defines the location of:
use Snicco\Component\Kernel\ValueObject\Directories;
$directories = new Directories(
__DIR__, // base directory,
__DIR__ .'/config', // config directory
__DIR__. '/var/cache', // cache directory
__DIR__ . '/var/log' // log directory
)
// This is equivalent to the above:
$directories = Directories::fromDefaults(__DIR__);The Kernel needs an instance of DIContainer, which is an abstract class that extends the PSR-11 container interface.
There are currently two implementations of this interface:
You can also provide your own implementation and test it using the test cases in snicco/kernel-testing.
The DIContainer class is an abstraction meant to be used inside bundles.
Since bundles are distributed packages, they can't rely on a specific dependency-injection container. However, the PSR-11 container interface only defines how to fetch services from the container, not how to define them, which is why the DIContainer abstraction is used.
Every .php file inside the config directory will be used to create a Config instance once the kernel is booted.
The following configuration inside your config directory:
// config/routing.php
return [
'route_directories' => [
/* */
]
'features' => [
'feature-a' => true,
]
]would be loaded into the config instance like so:
$config->get('routing');
$config->get('routing.route_directories');
$config->get('routing.features.feature-a');The kernel.php configuration file is reserved since this is where bundles and bootstrappers are defined:
// config/kernel.php
use Snicco\Component\Kernel\ValueObject\Environment;
return [
'bundles' => [
// These bundles will be used in all environments
Environment::ALL => [
RoutingBundle::class
],
// These bundles will only be used if the kernel environment is dev.
Environment::DEV => [
ProfilingBundle::class
],
],
// Bootstrappers are always used in all environments.
'bootstrappers' => [
BootstrapperA::class
]
]
use Snicco\Component\Kernel\Kernel;
$container = /* */
$env = /* */
$directories = /* */
$kernel = new Kernel(
$container,
$directories,
$env
);There is a difference in what happens when the kernel is booted based on the current environment and whether the configuration is already cached.
$kernel = /* */
$kernel->boot();The configure() method should be used to extend the loaded configuration with default values and to validate the configuration for the specific bundle. The configure() method is only called if the configuration is not cached yet.
The register() method should only be used to bind service definitions into the DIContainer.
The boot() method should be used to fetch services from the DIContainer and to configure them (if necessary). The container is already locked at this point and further modifications of service definitions are not possible. Attempting to modify the container from inside the boot() method of a bundle or bootstrapper will throw a ContainerIsLocked exception.
Each of these methods is always called first on all bundles, then on all bootstrappers.
This allows bootstrappers to customize behaviour of bundles (if desired).
There are two extension points in the booting process of the kernel.
use Snicco\Component\Kernel\Configuration\WritableConfig;use Snicco\Component\Kernel\Kernel;
$kernel = /* */
$kernel->afterConfigurationLoaded(function (WritableConfig $config) {
if( $some_condition ) {
$config->set('routing.features.feature-a', true);
}
});
$kernel->afterRegister(function (Kernel $kernel) {
if($some_condition) {
$kernel->container()->instance(LoggerInterface::class, new TestLogger());
}
});
$kernel->boot();After the container is booted, services provided by all bundles can be safely fetched.
An example:
use Nyholm\Psr7Server\ServerRequestCreator;
$kernel->boot();
$server_request_creator = $kernel->container()->make(ServerRequestCreator::class);
$http_kernel = $kernel->container()->make(HttpKernel::class);
$response = $http_kernel->handle($server_request_creator->fromGlobals());This repository is a read-only split of the development repo of the Snicco project.
This is how you can contribute.
Please report issues in the Snicco monorepo.
If you discover a security vulnerability, please follow our disclosure procedure.
| Back | FazBrowse Home | New Git URL |