1. Go to this page and download the library: Download firehed/container library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
// config/someDefinitionFile.php
declare(strict_types=1);
use Firehed\Container\TypedContainerInterface as TC;
use function Firehed\Container\env;
use function Firehed\Container\factory;
return [
// Env vars, with or without defaults
'SOME_ENV' => env('SOME_ENV'), // Reads env at runtime, returns as string (throws if not set)
'SOME_BOOL_ENV' => env('SOME_BOOL_ENV')->asBool(), // Env converted to boolean
'OPTIONAL_INT_ENV' => env('OPTIONAL_INT_ENV', '42')->asInt(), // Env with default value, converted to int
// Object types
MyService::class, // Autowired from constructor
MyInterface::class => MyImplementation::class, // Maps interface to implementation
// Classes with scalar parameters need explicit wiring
MyComplexService::class => function (TC $c) {
return new MyComplexService(
dep1: $c->get(MyInterface::class),
dep2: $c->get(MyService::class),
value1: $c->get('OPTIONAL_INT_ENV'),
);
},
// factory() definitions will call the definition on each access.
MyUniqueThing::class => factory(fn () => new MyUniqueThing()),
];
declare(strict_types=1);
// Include Composer's autoloader if not already done
{
Dotenv\Dotenv::createImmutable(__DIR__)->load();
}
*/
$isDevMode = getenv('ENVIRONMENT') === 'development';
if ($isDevMode) {
$builder = new Firehed\Container\Builder();
} else {
$builder = new Firehed\Container\Compiler();
}
// Each definition file must return a definition array (see below)
foreach (glob('config/*.php') as $definitionFile) {
$builder->addFile($definitionFile);
}
$container = $builder->build();
return $container; // Or use inline, as you see fit.
use function Firehed\Container\env;
return [
// Required, will throw if not set
'ENV_VAR_1' => env('ENV_VAR_1'),
// Optional, will return `default_value` if not set
'ENV_VAR_2' => env('ENV_VAR_2', 'default_value'),
// Optional, will return `null` if not set.
'ENV_VAR_3' => env('ENV_VAR_3', null),
// Counterexample - DO NOT do this!
'getenv' => getenv('VALUE_AT_COMPILE_TIME'),
];
return [
'ENV_VAR_1' => function () {
if (!array_key_exists('ENV_VAR_1', $_ENV) && getenv('ENV_VAR_1') === false) {
throw new Firehed\Container\Exceptions\EnvironmentVariableNotSet('ENV_VAR_1');
}
$value = $_ENV['ENV_VAR_1'] ?? geteenv('ENV_VAR_1');
if (!is_string($value)) {
throw new TypeError('$_ENV contained a non-string value for key ENV_VAR_1');
}
// For cast values, casting occurs here and can produce additional errors.
return $value;
},
];
use function Firehed\Container\env;
return [
'some_bool' => env('SOME_BOOL')->asBool(),
'some_int' => env('SOME_INT')->asInt(),
'some_float' => env('SOME_FLOAT')->asFloat(),
'some_enum' => env('SOME_ENUM')->asEnum(MyEnum::class),
];
return [
MyService::class,
];
// Given classes like this:
class MySpecialClass
{
}
class MyOtherClass
{
public function __construct(MySpecialClass $
return [
MySpecialClass::class,
MyOtherClass::class,
];
// $container->get(MyOtherClass::class) returns an instance of MyOtherClass with
// MySpecialClass provided to its constructor.
return [
MySpecialClass::class => function () {
return new MySpecialClass();
},
MyOtherClass::class => function (TypedContainerInterface $c) {
return new MyOtherClass($c->get(MySpecialClass::class));
},
];
> return [
> Doctrine\ORM\EntityManager::class => fn ($c) => Doctrine\ORM\EntityManager::create(...),
> // For autowiring the interface
> Doctrine\ORM\EntityManagerInterface::class => Doctrine\ORM\EntityManager::class,
> // Manual access, e.g. `$container->get('em')`.
> 'em' => Doctrine\ORM\EntityManager::class,
> ];
### Manual Wiring
If a class does not support autowiring or you'd prefer not to use it, provide a closure that returns a new implementation.
use function Firehed\Container\env;
return [
'isDevMode' => env('DEV', '0')->asBool(),
MyClass::class,
MyMockClass::class,
MyInterface::class => function ($c) {
if ($c->get('isDevMode')) {
return $c->get(MyMockClass::class);
}
return $c->get(MyClass::class);
},
];
use Psr\Container\ContainerInterface;
return [
// This will provide a single connection to your database, deferring the
// connection until either directly accessed or a service with PDO as a
// dependency is accessed.
// Note: you may opt to elide the `ContainerInterface` typehint for brevity
PDO::class => function (ContainerInterface $c) {
// This example assumes pdo_dsn, database_user, and database_pass are
// defined elsewhere (probably using the `env` helper)
return new PDO(
$c->get('pdo_dsn'),
$c->get('database_user'),
$c->get('database_pass')
);
},
];
use function Firehed\Container\factory;
return [
MyClass::class, // Autowired per above
DateTime::class => factory(fn() => new DateTime()),
];
$c1 = $container->get(MyClass::class);
$c2 = $container->get(MyClass::class);
assert($c1 === $c2, 'Non-factories return the same instance');
$dt1 = $container->get(DateTime::class);
$dt2 = $container->get(DateTime::class);
assert($dt1 !== $dt2, 'Factories return a new instance on each get() call');