php에서 psr11 의존항 주입 용기를 만드는 방법
19876 단어 phpoopdependencyinjectionpsr
용기
Dependency Injection, Principles, Practices, And Patterns에 따르면 의존항 주입용기는
a software library that provides DI functionality and allows automating many of the tasks involved in Object Composition, Interception, and Lifetime Management. DI Containers are also known as Inversion of Control (IoC) Containers
본고에서 우리는 의존 주입 실현psr11 인터페이스를 실현할 것이다.프로젝트 폴더로 이동하고 psr11 패키지를 설치하는 것이 첫 번째 방법입니다
composer require psr/psr-container
소프트웨어 패키지를 다운로드한 후 당신이 가장 좋아하는 텍스트 편집기를 엽니다. 저는 Tom을 사용하지만, 당신이 좋아하는 것은 무엇이든 사용할 수 있습니다.열다
composer.json
압축 파일 및 다음 코드 줄 입력autoload:{
psr-4: {
"Flixtechs\\": "src/"
}
}
새 파일을 만들고 호출하기index.php
그다음에 밑에.<?php
//add composer's autoloader
require 'vendor/autoload.php';
프로젝트 폴더에 새 파일 만들기src/Container.php
다음 코드 줄을 추가합니다<?php
namespace Flixtechs;
use Psr\Container\ContainerInterface;
class Container implements ContainerInterface
{
}
우리는 용기에서 키 값으로 등록된 항목을 추적하는 방법이 필요하다.entries 속성을 클래스에 추가/**
* Store all entries in the container
*/
protected $entries = [];
/**
* Store a list of instantiated singleton classes
*/
protected $instances = [];
/**
* Rules used to resolve the classes
*/
protected $rules = [];
지금 우리는 실시해야 한다get()
psr11 인터페이스에 추가하는 방법
class
```php
/**
* Finds an entry of the container by its identifier and returns it.
*
* @param string $id Identifier of the entry to look for.
*
* @throws NotFoundExceptionInterface No entry was found for **this** identifier.
* @throws ContainerExceptionInterface Error while retrieving the entry.
*
* @return mixed Entry.
*/
public function get($id)
{
if (!$this->has($id)) {
$this->set($id);
}
if ($this->entries[$id] instanceof \Closure || is_callable($this->entries[$id])) {
return $this->entries[$id]($this);
}
if (isset($this->rules['shared']) && in_array($id, $this->rules['shared'])) {
return $this->singleton($id);
}
return $this->resolve($id);
}
이런 방법은 시간이 좀 걸려요.$id
먼저 용기에 있는지 확인하고 없으면 추가합니다.항목의 값이 클립이면, 필요한 대상을 분석하는 클립을 호출합니다.다음에 검사할 거예요.$id
예.$shared
수조, 즉, 그것은 하나의 예류가 되어야 하며, 우리가 잠시 후에 볼 수 있는 예제 방법을 호출해야 한다.마지막으로, 상기 조건이 충족되지 않으면, 클래스를 가져오기 위해 리소스 방법을 사용합니다.어디 보자.
has()
메서드/**
* Returns true if the container can return an entry for the given identifier.
* Returns false otherwise.
*
* `has($id)` returning true does not mean that `get($id)` will not throw an exception.
* It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`.
*
* @param string $id Identifier of the entry to look for.
* @return bool
*/
public function has($id)
{
return isset($this->entries[$id]);
}
이 방법은 주어진 id가 있는지 확인하는 것뿐입니다$entries
어레이다음은
set()
메서드public function set($abstract, $concrete = null)
{
if(is_null($concrete)) {
$concrete = $abstract;
}
$this->entries[$abstract] = $concrete;
}
set 방법은 두 개의 매개 변수가 있는데, 각각 id와concrete이다.콘크리트는 폐쇄적이거나 완전한 유명일 수 있다.이제 다음 단계로 넘어갑시다.
resolve()
'마법'이 일어나는 방법/**
* Resolves a class name and creates its instance with dependencies
* @param string $class The class to resolve
* @return object The resolved instance
* @throws Psr\Container\ContainerExceptionInterface when the class cannot be instantiated
*/
public function resolve($alias)
{
$reflector = $this->getReflector($alias);
$constructor = $reflector->getConstructor();
if ($reflector->isInterface()) {
return $this->resolveInterface($reflector);
}
if (!$reflector->isInstantiable()) {
throw new ContainerException(
"Cannot inject {$reflector->getName()} to {$class} because it cannot be instantiated"
);
}
if (null === $constructor) {
return $reflector->newInstance();
}
$args = $this->getArguments($alias, $constructor);
return $reflector->newInstanceArgs($args);
}
이 방법은 id를 매개 변수로 하고, 이 종류를 실례화하려고 시도합니다.여기서 우리는 Reflection API를 사용하여 우리가 이런 종류를 해결하는 것을 돕는다.처음으로 전화를 했습니다.
getReflector()
주어진 id의 반사를 되돌려줍니다. 다음에 호출을 통해getConstructor()
반사기의 측정 방법.그리고 반사된 클래스가 인터페이스인지 확인한 다음, 이 방법을 사용해서 하나의 유형이 제시하는 인터페이스에서 클래스를 해석합니다. 잠시 후에 이 인터페이스를 볼 수 있습니다.다음에 반사된 클래스가 실례화되지 않으면 이상을 던진다.만약 클래스에 구조 함수가 없다면, 우리는 그것의 실례만 되돌려줄 것이다.
다음에 우리는 호출을 통해
getArguments()
우리 용기의 방법.그리고 호출을 통해newInstanceArgs($args)
반사기의 측정 방법.이것
getReflector()
메서드public function getReflector($alias)
{
$class = $this->entries[$alias];
try {
return (new \ReflectionClass($class));
} catch (\ReflectionException $e) {
throw new NotFoundException(
$e->getMessage(), $e->getCode()
);
}
}
이 방법은 entries 그룹에서 클래스를 가져옵니다.이 종류의 반사 클래스를 되돌려 보십시오. 실패하면 이상을 던집니다.당신은 스스로 이러한 이상을 실현할 수 있습니다이것
getArguments()
메서드/**
* Get the constructor arguments of a class
* @param ReflectionMethod $constructor The constructor
* @return array The arguments
*/
public function getArguments($alias, \ReflectionMethod $constructor)
{
$args = [];
$params = $constructor->getParameters();
foreach ($params as $param) {
if (null !== $param->getClass()) {
$args[] = $this->get(
$param->getClass()->getName()
);
} elseif ($param->isDefaultValueAvailable()) {
$args[] = $param->getDefaultValue();
} elseif (isset($this->rules[$alias][$param->getName()])) {
$args[] = $this->rules[$alias][
$param->getName()
];
}
}
return $args;
}
이 방법은 구조 함수의 별명과reflectionMethod를 사용한다.일컫다getParameters()
일련의 가져오기ReflectionParameters
. 다음 단계에서는 모든 매개변수를 반복합니다.우선 파라미터가 형식 알림 클래스인지 확인하고, 만약 그렇다면 호출합니다get()
방법으로 이 종류를 해석하다.클래스가 아니면 기본값이 있는지 확인합니다.기본값이 있으면 밀어넣기
$args
어레이매개변수가 유형 프롬프트 클래스가 아니며 기본값이 없으면 해당 값이 이미 있는지 확인합니다.$rules
통과configure()
메서드, 값을 밀어넣기$args
어레이마지막에 얘가 돌아왔어요.$args
어레이구성 방법은 단도직입적이다
public function configure(array $config)
{
$this->rules = array_merge($this->rules,$config);
return $this;
}
제가 빠뜨렸어요.resolveInterface()
및singleton()
방법은 유형 알림 인터페이스와signleton 클래스에서 클래스를 해석합니다.본문here에서 모든 코드를 찾을 수 있습니다우리 용기가 유효한지 봅시다
세 개의 클래스를 만듭니다
class Task
{
public function __conctruct(Logger $loger)
{
echo "task created\n";
}
}
class Logger
{
public function __construct(DB $database)
{
echo "Logger created\n";
}
}
class DB
{
public function __construct()
{
echo "DB created";
}
}
이제 Task 클래스를 인스턴스화하려는 경우전통적인 방식은 이렇습니다.$db = new DB();
$logger = new Logger($db);
$task = new Task($logger);
그러나, 우리의 DI 용기를 사용하면, 우리는 이렇게 할 것이다.이것을 너의 색인에 넣어라.php 파일use Flixtechs\Container;
$container = new Container;
$container->get(Task::class);
이 용기는 모든 물건을 담을 수 있다.빨리 달리다
composer dumpautoload
그리고 나서php index.php
다음 내용을 출력해야 합니다Db created
Logger created
Task created
이것은 생산에서 이 코드를 사용할 수 없는 방법이다. 비록 DI용기의 마력을 설명하고 싶지만, 처음부터 자신의 코드를 구축하는 방법을 보여 주고 싶다.하지만 너는 여기서 개선할 수 있다.
Reference
이 문제에 관하여(php에서 psr11 의존항 주입 용기를 만드는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/slimgee/how-to-create-a-psr11-dependency-injection-container-in-php-479a텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)