PHP 의존 주입 컨테이너를 만듭니다.

100달러짜리 신용카드를 받다


PHP 의존 주입 컨테이너를 만들고 Laravel에서 의존 및 매개변수 부팅 컨트롤러 및 방법을 학습합니다.



우리는 Laravel를 사용하여 프로그램을 구축하고 있지만, 우리들 중 많은 사람들이 Laravel 의존항과 파라미터 시작 컨트롤러와 방법을 어떻게 사용하는지 모른다.
우리가 선포한 노선은 다음과 같다.
Route::get('hello', 'TestController@index')
우리의 디렉터는 다음과 같습니다.

 namespace App\Http\Controllers\Test;


 class TestController extends Controller
 {
      private $requests;

      public function __construct( Request $request)
         {
            $this->requests = $request;
         }


     /**
      * Show the application dashboard.
      */
     public function index(TestModel $testModel)
     {
       return $testModel->get();
     }


 }

또는 이와 같은 노선:
Route::get('hello', 'TestController')
다음과 같은 컨트롤러도 있습니다.

 namespace App\Http\Controllers\Test;


 class TestController extends Controller
 {
      private $requests;

      public function __construct( Request $request)
         {
            $this->requests = $request;
         }


     /**
      * Show the application dashboard.
      */
     public function __invoke(TestModel $testModel)
     {
       return $testModel->get();
     }


 }

문제는 다음과 같습니다.
1.1 Laravel은 어떻게 구조의 의존 관계와 주입을 검측합니까?
1.2와 Laravel은 어떻게 구조의 의존항을 사용하여 클래스를 초기화하고 그 의존항과 파라미터를 사용하여'인덱스'방법을 호출합니까?
2.1 방법명은 전달하지 않지만 Laravel은 기본값으로 호출 방법을 어떻게 감지합니까?
주입 용기에 의존해서 앞의 문제를 이해하도록 하자.

왜 우리가 알아야 합니까?

  • 개발자로서 Laravel이 어떻게 일을 하는지 알아야 합니다.
  • 그것은 우리가 자신의 방식으로 새로운 틀을 세우는 데 도움을 줄 것이다.
  • 우리는 이 용기를 우리의 대형 프로젝트나 모듈에 사용할 수 있다.
  • 마지막으로, 우리는 공부를 시작할 것이다Laravel(최고)
  • PHP 반사 우리 시작하자.


    우리들의 발걸음
  • 클래스 만들기
  • 클래스를 초기화하고 구조 함수에 대한 의존항과 매개 변수를 주입하는 방법(make)을 만듭니다
  • 추출 클래스와 방법을 추출하고 이 방법의 의존항과 파라미터를 주입하는 방법(호출)을 만듭니다
  • 1. 클래스를 만듭니다.


    class DependencyInjectionContainer
    {
    
        /**
         * The container's  instance.
         *
         * @var static
         */
        protected static $instance;
    
    
        /**
         * the class name with namespace
         *
         * @var string
         */
        protected $callbackClass;
    
        /**
         * the method name of provided class
         *
         * @var string
         */
        protected $callbackMethod;
    
        /**
         * method separator of a class. when pass class and method as string
         */
        protected $methodSeparator = '@';
    
        /**
         * namespace  for  class. when pass class and method as string
         *
         * @var string
         */
        protected $namespace = "App\\controller\\";
    
    
        /**
         *   get Singleton instance of the class
         *
         * @return static
         */
        public static function instance()
        {
    
        }
    
        /**
         * @param $callable -- string class and method name with separator @
         * @param  array  $parameters
         */
        public function call($callable, $parameters = [])
        {
    
        }
    
    
        /**
         * separate class and method name
         * @param $callback
         */
        private function resolveCallback($callback)
        {
    
        }
    
        /**
         * instantiate class with dependency and return class instance
         * @param $class - class name
         * @param $parameters (optional) -- parameters as array . If constructor need any parameter
         */
        public function make($class, $parameters = [])
        {
        }
    
    }
    

    클래스를 초기화하고 구조 함수에 의존하는 항목과 파라미터를 주입하는 방법 (make) 만들기


    PHP 를 사용하겠습니다.이 섹션에서는 PHPPHP Reflection 개체를 사용합니다.PHPReflactionClass에는 여러 가지 방법이 있습니다.
    이 절에서, 우리는 클래스 실례를 만들어야 한다.
    만약 우리가 어떤 종류의 실례를 만들면, 모든 의존항과 파라미터를 전달하고 주입해야 한다는 것을 우리는 알고 있다.
    PHPReflactionClass를 사용하려면 모든 종속성을 테스트해야 합니다.
    public function make($class, $parameters = [])
        {
            $classReflection = new ReflectionClass($class);
            $constructorParams = $classReflection->getConstructor()->getParameters();
       }
    
    위 코드에서 구조 함수의 모든 매개 변수를 $constructorParams 변수로 수집합니다.
    그리고 $constructorParams를 사용하여 매개 변수와 의존 관계를 순환하고 검사해야 합니다.
    public function make($class, $parameters = [])
        {
    
            $classReflection = new ReflectionClass($class);
            $constructorParams = $classReflection->getConstructor()->getParameters();
            $dependencies = [];
    
            /*
             * loop with constructor parameters or dependency
             */
            foreach ($constructorParams as $constructorParam) {
    
                $type = $constructorParam->getType();
    
                if ($type && $type instanceof ReflectionNamedType) {
    
                    echo "It is a class and we need to instantiate the class and pass to constructor"
    
                } else {
    
                    echo "This is a normal parameter and We need to find parameter value from $parameters . If not found value then needs to check if this parameter is optional or not. If not optional then through error"
    
                }
    
            } 
        }
    
    주요 사항:
  • 매개 변수가 하나의 클래스라면 이 클래스를 실례화하여 구조 함수에 전달해야 한다.
  • Parameter가 클래스가 아니면 $parameters에서 매개 변수 값을 찾아야 합니다.값을 찾을 수 없으면 이 매개 변수를 선택할 수 있는지 확인해야 합니다.선택할 수 없는 경우 오류를 통과합니다.
  • Make 방법을 최종적으로 결정합니다.
    public function make($class, $parameters = [])
        {
    
            $classReflection = new ReflectionClass($class);
            $constructorParams = $classReflection->getConstructor()->getParameters();
            $dependencies = [];
    
            /*
             * loop with constructor parameters or dependency
             */
            foreach ($constructorParams as $constructorParam) {
    
                $type = $constructorParam->getType();
    
                if ($type && $type instanceof ReflectionNamedType) {
    
                    // make instance of this class :
                    $paramInstance = $constructorParam->getClass()->newInstance()
    
                    // push to $dependencies array
                    array_push($dependencies, $paramInstance);
    
                } else {
    
                    $name = $constructorParam->getName(); // get the name of param
    
                    // check this param value exist in $parameters
                    if (array_key_exists($name, $parameters)) { // if exist
    
                        // push  value to $dependencies sequencially
                        array_push($dependencies, $parameters[$name]);
    
                    } else { // if not exist
    
                        if (!$constructorParam->isOptional()) { // check if not optional
                            throw new Exception("Can not resolve parameters");
                        }
    
                    }
    
                }
    
            }
            // finally pass dependancy and param to class instance 
            return $classReflection->newInstance(...$dependencies);
        }
    
    나는 코드로 모든 것을 설명한다.
    좋아...우리는 이미 클래스의 의존항 주입 용기를 완성했다
    단일 인스턴스를 만듭니다.
      public static function instance()
        {
    
            if (is_null(static::$instance)) {
                static::$instance = new static;
            }
    
            return static::$instance;
        }
    
    기본용법
     $container =  DependencyInjectionContainer::instance();
    
    클래스 정의
    class MyClass
    {
        private $dependency;
    
        public function __construct(AnotherClass $dependency)
        {
            $this->dependency = $dependency;
        }
    }
    
    new MyClass 대신 용기를 사용하는 make() 방법:
    $instance = $container->make(MyClass::class);
    
    컨테이너가 의존 항목을 자동으로 실례화하므로 이 기능은 다음과 같습니다.
    $instance = new MyClass(new AnotherClass());
    
    인스턴스
    다음은 메일 프로그램 기능과 사용자 등록을 분리하는 ReflactionClass 기반의 보다 실용적인 예입니다.
    class Mailer
    {
        public function mail($recipient, $content)
        {
            // Send an email to the recipient
            // ...
        }
    }
    
    class UserManager
    {
        private $mailer;
    
        public function __construct(Mailer $mailer)
        {
            $this->mailer = $mailer;
        }
    
        public function register($email, $password)
        {
            // Create the user account
    
        }
    }
    
    
    
    $container = DependencyInjectionContainer::instance();
    
    $userManager = $container->make(UserManager::class);
    $userManager->register('[email protected]', 'MySuperSecurePassword!');
    

    PHP-DI 설명서 3. 클래스와 방법을 추출하고 이 방법의 의존항과 파라미터를 주입하는 방법(호출)을 만듭니다.


    이 섹션에서는 Laravel이 컨트롤러와 방법을 어떻게 해석하고 의존항/파라미터를 사용하여 시작하는지 알아보겠습니다.
    층계
  • 독립 실행형 컨트롤러 및 방법
  • 검측 방법의 관련성/파라미터와 호출 방법
  • 우리 거 써.make()기능
  • 1. 별도의 컨트롤러 및 방법
    클래스에는 클래스 이름과 방법 이름을 구분하는 구분자로 $methodSeparator의 속성이 있습니다.
     private function resolveCallback($callable)
        {
    
            //separate class and method
            $segments = explode($this->methodSeparator, $callable);
    
            // set class name with namespace
            $this->callbackClass = $this->namespace.$segments[0]; 
    
            // set method name . if method name not provided then default method __invoke
            $this->callbackMethod = isset($segments[1]) ? $segments[1] : '__invoke'; 
    
        }
    
    2. 검측 방법의 관련성/파라미터와 호출 방법
     public function call($callable, $parameters = [])
        {
    
            // set class name with namespace and method name
            $this->resolveCallback($callable);
    
            // initiate ReflectionMethod with class and method 
            $methodReflection = new ReflectionMethod($this->callbackClass, $this->callbackMethod);
    
            // get all dependencies/parameters
            $methodParams = $methodReflection->getParameters();
    
            $dependencies = [];
    
            // loop with dependencies/parameters
            foreach ($methodParams as $param) {
    
                $type = $param->getType(); // check type
    
                if ($type && $type instanceof ReflectionNamedType) { /// if parameter is a class
    
                    $name = $param->getClass()->newInstance(); // create insrance 
                    array_push($dependencies, $name); // push  to $dependencies array
    
                } else {  /// Normal parameter  
    
                    $name = $param->getName();
    
                    if (array_key_exists($name, $parameters)) { // check exist in $parameters
    
                        array_push($dependencies, $parameters[$name]); // push  to $dependencies array
    
                    } else { // if not exist
    
                        if (!$param->isOptional()) { // check if not optional
                            throw new Exception("Can not resolve parameters");
                        }
                    }
    
                }
    
            }
    
            // make class instance
            $initClass = $this->make($this->callbackClass, $parameters);
    
            // call method with $dependencies/parameters
           return $methodReflection->invoke($initClass, ...$dependencies); 
        }
    
    이제 Laravel에서 호출 함수의 매개 변수를 수집하는 방법에 대한 질문이 있습니다.
    동적 매개변수를 사용하여 라우트를 선언할 때, 예를 들면 다음과 같습니다.
    Route::get('hello/{name}', 'TestController@index')
    
    Laravel 라우팅 시스템은 모든 매개변수를 수집하여 호출 기능에 전달합니다.
    $parameters = ["name" => "AL EMRAN" ];
    $container->cal("TestController@index", $parameters)
    
    
    사용법
    $container->call('TestController@index');
    $container->call('TestController@show', ['id' => 4]);
    
    $container->call('TestController');
    $container->call('TestController', ['id' => 4]);
    
    
    혹은
    예.
    
    class TestController 
    {
         protected $company;
         public function __construct(Company $company)
            {
                $this->company =  $company ;
            }
    
        /**
         * @param  Request  $request 
         */
        public function index(Request $request){
    
        $company =  $company->get();
    
         return view('admin.company', compact('company'));        
    
        }
    
    }
    
    
    다음과 같은 이점을 누릴 수 있습니다.
       $instance = DependencyInjectionContainer::instance();
       $instance->namespace = "App\\Http\Controllers\\Admin\\"; // change namespace
    
       $class = $instance->make(CompanyController::class); // make class instance
    
       $instance->call(["CompanyController", 'index']); // call method
    
       $instance->call([$class, 'index']); // or--call method
    

    패키지 설치


    패키지Github 링크
    composer require emrancu/dependency-injection-container
    

    여기 있다 설교자


    Laravel 의존 주입 용기는 매우 방대하며, 그것의 루트 시스템도 마찬가지다.내가 이 부류를 만든 것은 단지 이해하기 위해서이다.
    첫 번째 기사입니다. 귀하의 의견을 평가하거나 " "로 이메일을 보내 주십시오.
    아이디어[email protected]
    Here

    좋은 웹페이지 즐겨찾기