Skip to content

Instantly share code, notes, and snippets.

@RatulHasan
Last active March 10, 2023 12:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RatulHasan/cf7bbd3468371b3bf76140443be68222 to your computer and use it in GitHub Desktop.
Save RatulHasan/cf7bbd3468371b3bf76140443be68222 to your computer and use it in GitHub Desktop.
PSR-11
<?php
use Psr\Container\ContainerInterface;
class AppContainer implements ContainerInterface {
private array $instances = [];
public function get( string $id ) {
if ( $this->has( $id ) ) {
return $this->instances[ $id ];
}
try {
$instance = $this->createObject( $id );
} catch ( \ReflectionException $e ) {
return $e;
}
$this->instances[ $id ] = $instance;
return $instance;
}
public function has( string $id ): bool {
return isset( $this->instances[ $id ] );
}
/**
* Create Object.
*
* @param string $className
*
* @return mixed|object|\ReflectionException|string|null
*/
private function createObject( string $className ) {
// If this class exists or not
if ( ! class_exists( $className ) ) {
return new \ReflectionException( '404', "Class: {$className} doesn't exists." );
}
// If the class has a constructor or not.
$reflection = new \ReflectionClass( $className );
if ( null === $reflection->getConstructor() ) {
return new $className;
}
// Get all the parameters.
$parameters = $reflection->getConstructor()->getParameters();
try {
$dependencies = $this->buildDependencies( $parameters );
} catch ( \ReflectionException $e ) {
return $e;
}
try {
return $reflection->newInstanceArgs( $dependencies );
} catch ( \ReflectionException $e ) {
return $e;
}
}
/**
* Build Dependencies.
*
* @param ReflectionParameter[] $parameters
*
* @return array
*/
private function buildDependencies( array $parameters ): array {
$dependencies = [];
foreach ( $parameters as $parameter ) {
$dependencies[] = $this->createObject( $parameter->getClass()->getName() );
}
return $dependencies;
}
}
Class Car {
private Engine $engine;
public function __construct(Engine $engine) {
$this->engine = $engine;
}
public function getCar(): string {
return 'Car with ' . $this->getEngine();
}
public function getEngine(): string {
return $this->engine->getName();
}
}
Class Engine {
private string $name;
public function __construct() {
$this->name = 'v8 Engine';
}
public function getName(): string {
return $this->name;
}
}
// Use
$car = new Car(new Engine());
echo $car->getCar();
echo PHP_EOL;
die();
// Use with PSR-11
$container = new AppContainers();
try {
$app = $container->get( Car::class );
$car = $app->get(Vehicle::class);
echo $car->getCar();
echo PHP_EOL;
} catch ( NotFoundExceptionInterface|ContainerExceptionInterface $e ) {
echo $e->getMessage();
die($e->getCode());
}
// In composer.json
"psr/container": "^2.0"
// or,
composer require psr/container
// Useful link
https://www.php-fig.org/psr/psr-11/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment