목차
생성자 메서드 주입
构造方法注入" >构造方法注入
Setter 方法注入" >Setter 方法注入
接口注入
优势
控制反转" >控制反转
Laravel Ioc
인터페이스 주입
장점
小贴士" >小贴士
最后" >最后
PHP 프레임워크 Laravel Laravel의 종속성 주입 및 IoC

Laravel의 종속성 주입 및 IoC

Jun 15, 2020 pm 05:57 PM
laravel

Laravel의 종속성 주입 및 IoC종속성 주입

종속성 주입이라는 용어는 Martin Fowler가 제안한 용어로, 애플리케이션에 구성 요소를 주입하는 행위입니다. Ward Cunningham이 말했듯이:

종속성 주입은 민첩한 아키텍처의 핵심 요소입니다.

예를 살펴보겠습니다.
class UserProvider{
    protected $connection;

    public function __construct(){
        $this->connection = new Connection;
    }

    public function retrieveByCredentials( array $credentials ){
        $user = $this->connection
                        ->where( 'email', $credentials['email'])
                        ->where( 'password', $credentials['password'])
                        ->first();

        return $user;
    }
}
로그인 후 복사

이 클래스를 테스트하거나 유지하려면 데이터베이스 인스턴스에 액세스하여 일부 쿼리를 수행해야 합니다. 이런 일을 피하려면 이 클래스를 다른 클래스에서

de커플링
할 수 있습니다. 세 가지 옵션 중 하나를 사용하여 Connection 클래스를 직접 사용하지 않고 삽입할 수 있습니다.

클래스에 구성 요소를 주입할 때 다음 세 가지 옵션 중 하나를 사용할 수 있습니다.

생성자 메서드 주입

class UserProvider{
    protected $connection;

    public function __construct( Connection $con ){
        $this->connection = $con;
    }
    ...
로그인 후 복사

Connection 类注入而不需要直接使用它。

将组件注入类时,可以使用以下三个选项之一:

构造方法注入

class UserProvider{
    protected $connection;
    public function __construct(){
        ...
    }

    public function setConnection( Connection $con ){
        $this->connection = $con;
    }
    ...
로그인 후 복사

Setter 方法注入

同样,我们也可以使用 Setter 方法注入依赖关系:

interface ConnectionInjector{
    public function injectConnection( Connection $con );
}

class UserProvider implements ConnectionInjector{
    protected $connection;

    public function __construct(){
        ...
    }

    public function injectConnection( Connection $con ){
        $this->connection = $con;
    }
}
로그인 후 복사

接口注入

class FileSessionStorage{
  public function __construct(){
    session_start();
  }

  public function get( $key ){
    return $_SESSION[$key];
  }

  public function set( $key, $value ){
    $_SESSION[$key] = $value;
  }
}

class SimpleAuth{
  protected $session;

  public function __construct(){
    $this->session = new FileSessionStorage;
  }
}

//创建一个 SimpleAuth
$auth = new SimpleAuth();
로그인 후 복사

当一个类实现了我们的接口时,我们定义了 injectConnection 方法来解决依赖关系。

优势

现在,当测试我们的类时,我们可以模拟依赖类并将其作为参数传递。每个类必须专注于一个特定的任务,而不应该关心解决它们的依赖性。这样,你将拥有一个更专注和可维护的应用程序。

如果你想了解更多关于 DI 的信息,Alejandro Gervassio 在 本系列 文章中对其进行了广泛而专业的介绍,所以一定要去读这些文章。那么,什么又是 IoC 呢?IoC (控制反转)不需要使用依赖注入,但它可以帮助你有效的管理依赖关系。

控制反转

Ioc 是一个简单的组件,可以更加方便地解析依赖项。你可以将对象形容为容器,并且每次解析类时,都会自动注入依赖项。

Laravel Ioc

当你请求一个对象时, Laravel Ioc 在解决依赖关系的方式上有些特殊:

我们使用一个简单的例子,将在本文中改进它。
SimpleAuth 类依赖于 FileSessionStorage ,所以我们的代码可能是这样的:

class SimpleAuth{
  protected $session;

  public function __construct( FileSessionStorage $session ){
    $this->session = $session;
  }
}
로그인 후 복사

这是一种经典的方法,让我们从使用构造函数注入开始。

$auth = new SimpleAuth( new FileSessionStorage() );
로그인 후 복사

现在我们创建一个对象:

App::bind( 'FileSessionStorage', function(){
    return new FileSessionStorage;
});
로그인 후 복사

现在我想使用 Laravel Ioc 来管理这一切。

因为 Application 类继承自 Container 类,所以你可以通过 App 门面来访问容器。

class MysqlSessionStorage{

  public function __construct(){
    //...
  }

  public function get($key){
    // do something
  }

  public function set( $key, $value ){
    // do something
  }
}
로그인 후 복사

bind 方法第一个参数是要绑定到容器的唯一 ID ,第二个参数是一个回调函数每当执行 FileSessionStorage 类时执行,我们还可以传递一个表示类名的字符串,如下所示。

Note: 如果你查看 Laravel 包时,你将看到绑定有时会分组,比如( viewview.finder……)。

假设我们将会话存储转换为 Mysql 存储,我们的类应该类似于:

interface SessionStorage{
  public function get( $key );
  public function set( $key, $value );
}
로그인 후 복사

现在我们已经更改了依赖项,我们还需要更改 SimpleAuth 构造函数,并将新对象绑定到容器中!

高级模块不应该依赖于低级模块,两者都应该依赖于抽象对象。
抽象不应该依赖于细节,细节应该取决于抽象。

Robert C. Martin

我们的 SimpleAuth 类不应该关心我们的存储是如何完成的,相反它更应该关注于消费的服务。

因此,我们可以抽象实现我们的存储:

class FileSessionStorage implements SessionStorage{

  public function __construct(){
    //...
  }

  public function get( $key ){
    //...
  }

  public function set( $key, $value ){
    //...
  }
}

class MysqlSessionStorage implements SessionStorage{

  public function __construct(){
    //...
  }

  public function get( $key ){
    //...
  }

  public function set( $key, $value ){
    //...
  }
}

class SimpleAuth{

  protected $session;

  public function __construct( SessionStorage $session ){
    $this->session = $session;
  }

}
로그인 후 복사

这样我们就可以实现并请求 SessionStorage 接口的实例:

Uncaught exception 'Illuminate\Container\BindingResolutionException' with message 'Target [SessionStorage] is not instantiable.'
로그인 후 복사

如果我们使用 App::make('SimpleAuth') 通过容器解析 SimpleAuth
类,容器将会抛出 BindingResolutionExceptionSetter 메서드 주입

마찬가지로 우리는 Setter 메서드를 사용하여 종속성을 주입할 수도 있습니다.

App:bind( 'SessionStorage', 'MysqlSessionStorage' );
로그인 후 복사
로그인 후 복사

인터페이스 주입

rrreee🎜 클래스가 인터페이스를 구현할 때 종속성을 해결하기 위해 injectConnection 메서드를 정의합니다. 🎜

장점

🎜이제 클래스를 테스트할 때 종속 클래스를 모의하고 매개변수로 전달할 수 있습니다. 각 클래스는 특정 작업에 집중해야 하며 종속성을 해결하는 데 관심을 가져서는 안 됩니다. 이렇게 하면 더욱 집중적이고 유지 관리가 쉬운 애플리케이션을 갖게 됩니다. 🎜🎜DI에 대해 더 자세히 알고 싶다면 Alejandro Gervassio가 이 기사 시리즈에서 DI에 대해 광범위하고 전문적으로 다루었으니 꼭 읽어보세요. 그렇다면 IoC란 무엇인가? IoC(Inversion of Control)에서는 종속성 주입을 사용할 필요가 없지만 종속성을 효과적으로 관리하는 데 도움이 될 수 있습니다. 🎜🎜🎜Inversion of Control🎜🎜🎜Ioc는 종속성을 더 쉽게 해결할 수 있는 간단한 구성 요소입니다. 개체를 컨테이너로 설명할 수 있으며 클래스가 해결될 때마다 종속성이 자동으로 주입됩니다. 🎜

Laravel Ioc

🎜Laravel Ioc은 객체를 요청할 때 종속성을 해결하는 방식에서 다소 특별합니다: 🎜🎜🎜🎜이 기사에서는 간단한 예를 사용하여 이를 개선하겠습니다.
SimpleAuth 클래스는 FileSessionStorage에 의존하므로 코드는 다음과 같습니다. 🎜rrreee🎜이것은 고전적인 접근 방식입니다. 생성자를 사용하여 시작하겠습니다. . 🎜rrreee🎜이제 객체를 생성합니다: 🎜rrreee🎜이제 Laravel Ioc을 사용하여 이 모든 것을 관리하겠습니다. 🎜🎜 Application 클래스는 Container 클래스에서 상속되기 때문에 App 파사드를 통해 컨테이너에 액세스할 수 있습니다. 🎜rrreee🎜bind 메소드의 첫 번째 매개변수는 컨테이너에 바인딩할 고유 ID이고, 두 번째 매개변수는 FileSessionStorage 클래스가 실행될 때마다 실행되는 콜백 함수입니다. 아래와 같이 클래스 이름을 나타내는 문자열을 전달할 수도 있습니다. 🎜🎜참고: Laravel 패키지를 보면 바인딩이 때때로 ( view, view.finder)와 같이 그룹화되어 있는 것을 볼 수 있습니다. … …). 🎜🎜 세션 저장소를 Mysql 저장소로 변환한다고 가정하면 클래스는 다음과 같아야 합니다. 🎜rrreee🎜 이제 종속성을 변경했으므로 SimpleAuth 생성자를 변경하고 새 개체 Set을 바인딩해야 합니다. 용기에! 🎜🎜🎜고수준 모듈은 저수준 모듈에 의존해서는 안 되며, 둘 다 추상 객체에 의존해야 합니다.
추상은 세부사항에 의존해서는 안 되고, 세부사항은 추상화에 의존해야 합니다. 🎜🎜Robert C. Martin🎜🎜🎜우리 SimpleAuth 클래스는 저장이 어떻게 이루어지는지 신경쓰지 말고, 대신 서비스 소비에 집중해야 합니다. 🎜🎜그러므로 우리는 저장소를 추상적으로 구현할 수 있습니다: 🎜rrreee🎜이 방법으로 SessionStorage 인터페이스의 인스턴스를 구현하고 요청할 수 있습니다: 🎜rrreee🎜 App::make('를 사용하는 경우 SimpleAuth ') 컨테이너를 통해 SimpleAuth
클래스를 구문 분석합니다. 컨테이너는 바인딩에서 클래스를 확인하려고 시도한 후 BindingResolutionException을 반환합니다. 리플렉션 메서드에 추가하고 모든 종속성을 해결합니다. 🎜rrreee🎜컨테이너가 인터페이스를 인스턴스화하려고 합니다. 이 인터페이스에 대해 특정 바인딩을 만들 수 있습니다. 🎜
App:bind( 'SessionStorage', 'MysqlSessionStorage' );
로그인 후 복사
로그인 후 복사

现在每次我们尝试从容器解析该接口时,我们会得到一个 MysqlSessionStorage 实例。如果我们想要切换我们的存储服务,我们只要变更一下这个绑定。

Note: 如果你想要查看一个类是否已经在容器中被绑定,你可以使用 App::bound('ClassName') ,或者可以使用 App::bindIf('ClassName') 来注册一个还未被注册过的绑定。

Laravel Ioc 也提供 App::singleton('ClassName', 'resolver') 来处理单例的绑定。
你也可以使用 App::instance('ClassName', 'instance') 来创建单例的绑定。
如果容器不能解析依赖项就会抛出 ReflectionException ,但是我们可以使用 App::resolvingAny(Closure) 方法以回调函数的形式来解析任何指定的类型。

Note: 如果你为某个类型已经注册了一个解析方式 resolvingAny 方法仍然会被调用,但它会直接返回 bind 方法的返回值。

小贴士

  • 这些绑定写在哪儿:
    如果只是一个小型应用你可以写在一个全局的起始文件 global/start.php 中,但如果项目变得越来越庞大就有必要使用 Service Provider 。
  • 测试:
    当需要快速简易的测试可以考虑使用 php artisan tinker ,它十分强大,且能帮你提升你的 Laravel 测试流程。
  • Reflection API:
    PHP 的 Reflection API 是非常强大的,如果你想要深入 Laravel Ioc 你需要熟悉 Reflection API ,可以先看下这个 教程 来获得更多的信息。

最后

和往常一样,学习或者了解某些东西最好的方法就是查看源代码。Laravel Ioc 仅仅只是一个文件,不会花费你太多时间来完成所有功能。你想了解更多关于 Laravel Ioc 或者 Ioc 的一般情况吗?那请告诉我们吧!

推荐教程:《Laravel教程

위 내용은 Laravel의 종속성 주입 및 IoC의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

PHP에서 ORM(객체 관계형 매핑)을 사용하여 데이터베이스 작업을 단순화하는 방법은 무엇입니까? PHP에서 ORM(객체 관계형 매핑)을 사용하여 데이터베이스 작업을 단순화하는 방법은 무엇입니까? May 07, 2024 am 08:39 AM

PHP의 데이터베이스 작업은 객체를 관계형 데이터베이스에 매핑하는 ORM을 사용하여 단순화됩니다. Laravel의 EloquentORM을 사용하면 객체 지향 구문을 사용하여 데이터베이스와 상호 작용할 수 있습니다. 모델 클래스를 정의하거나 Eloquent 메소드를 사용하거나 실제로 블로그 시스템을 구축하여 ORM을 사용할 수 있습니다.

PHP 단위 테스트 도구의 장점과 단점 분석 PHP 단위 테스트 도구의 장점과 단점 분석 May 06, 2024 pm 10:51 PM

PHP 단위 테스트 도구 분석: PHPUnit: 대규모 프로젝트에 적합하고 포괄적인 기능을 제공하며 설치가 쉽지만 장황하고 느릴 수 있습니다. PHPUnitWrapper: 소규모 프로젝트에 적합하고 사용하기 쉽고 Lumen/Laravel에 최적화되어 있지만 기능이 제한적이고 코드 적용 범위 분석을 제공하지 않으며 커뮤니티 지원이 제한되어 있습니다.

Laravel과 CodeIgniter의 최신 버전 비교 Laravel과 CodeIgniter의 최신 버전 비교 Jun 05, 2024 pm 05:29 PM

Laravel 9 및 CodeIgniter 4의 최신 버전은 업데이트된 기능과 개선 사항을 제공합니다. Laravel9은 MVC 아키텍처를 채택하여 데이터베이스 마이그레이션, 인증, 템플릿 엔진 등의 기능을 제공합니다. CodeIgniter4는 HMVC 아키텍처를 사용하여 라우팅, ORM 및 캐싱을 제공합니다. 성능면에서는 Laravel9의 서비스 제공자 기반 디자인 패턴과 CodeIgniter4의 경량 프레임워크가 뛰어난 성능을 제공합니다. 실제 애플리케이션에서 Laravel9은 유연성과 강력한 기능이 필요한 복잡한 프로젝트에 적합한 반면, CodeIgniter4는 빠른 개발 및 소규모 애플리케이션에 적합합니다.

Laravel - 장인 명령 Laravel - 장인 명령 Aug 27, 2024 am 10:51 AM

Laravel - Artisan Commands - Laravel 5.7은 새로운 명령을 처리하고 테스트하는 새로운 방법을 제공합니다. 여기에는 장인 명령을 테스트하는 새로운 기능이 포함되어 있으며 데모는 아래에 언급되어 있습니다.

Laravel과 CodeIgniter의 데이터 처리 기능은 어떻게 비교됩니까? Laravel과 CodeIgniter의 데이터 처리 기능은 어떻게 비교됩니까? Jun 01, 2024 pm 01:34 PM

Laravel과 CodeIgniter의 데이터 처리 기능을 비교해 보세요. ORM: Laravel은 클래스-객체 관계형 매핑을 제공하는 EloquentORM을 사용하는 반면, CodeIgniter는 데이터베이스 모델을 PHP 클래스의 하위 클래스로 표현하기 위해 ActiveRecord를 사용합니다. 쿼리 빌더: Laravel에는 유연한 체인 쿼리 API가 있는 반면, CodeIgniter의 쿼리 빌더는 더 간단하고 배열 기반입니다. 데이터 검증: Laravel은 사용자 정의 검증 규칙을 지원하는 Validator 클래스를 제공하는 반면, CodeIgniter는 내장된 검증 기능이 적고 사용자 정의 규칙을 수동으로 코딩해야 합니다. 실제 사례: 사용자 등록 예시에서는 Lar를 보여줍니다.

Laravel과 CodeIgniter: 대규모 프로젝트에는 어떤 프레임워크가 더 좋나요? Laravel과 CodeIgniter: 대규모 프로젝트에는 어떤 프레임워크가 더 좋나요? Jun 04, 2024 am 09:09 AM

대규모 프로젝트를 위한 프레임워크를 선택할 때 Laravel과 CodeIgniter는 각각 고유한 장점을 가지고 있습니다. Laravel은 엔터프라이즈급 애플리케이션을 위해 설계되었으며 모듈식 디자인, 종속성 주입 및 강력한 기능 세트를 제공합니다. CodeIgniter는 속도와 사용 편의성을 강조하여 중소 규모 프로젝트에 더 적합한 경량 프레임워크입니다. 요구 사항이 복잡하고 사용자 수가 많은 대규모 프로젝트의 경우 Laravel의 성능과 확장성이 더 적합합니다. 간단한 프로젝트나 리소스가 제한된 상황에서는 CodeIgniter의 가볍고 빠른 개발 기능이 더 이상적입니다.

Laravel과 CodeIgniter 중 어느 것이 더 초보자에게 적합합니까? Laravel과 CodeIgniter 중 어느 것이 더 초보자에게 적합합니까? Jun 05, 2024 pm 07:50 PM

초보자의 경우 CodeIgniter는 학습 곡선이 더 완만하고 기능이 적지만 기본적인 요구 사항을 충족합니다. Laravel은 더 넓은 기능 세트를 제공하지만 학습 곡선이 약간 더 가파릅니다. 성능면에서는 Laravel과 CodeIgniter 모두 좋은 성능을 보입니다. Laravel은 보다 광범위한 문서와 적극적인 커뮤니티 지원을 제공하는 반면 CodeIgniter는 더 간단하고 가벼우며 강력한 보안 기능을 갖추고 있습니다. 블로그 애플리케이션을 구축하는 실제 사례에서 Laravel의 EloquentORM은 데이터 조작을 단순화하는 반면 CodeIgniter는 더 많은 수동 구성이 필요합니다.

PHP 코드 단위 테스트 및 통합 테스트 PHP 코드 단위 테스트 및 통합 테스트 May 07, 2024 am 08:00 AM

PHP 단위 및 통합 테스트 가이드 단위 테스트: 단일 코드 또는 함수 단위에 중점을 두고 PHPUnit을 사용하여 검증용 테스트 케이스 클래스를 만듭니다. 통합 테스트: 여러 코드 단위가 함께 작동하는 방식에 주의를 기울이고 PHPUnit의 setUp() 및 TearDown() 메서드를 사용하여 테스트 환경을 설정하고 정리합니다. 실제 사례: PHPUnit을 사용하여 데이터베이스 생성, 서버 시작 및 테스트 코드 작성을 포함하여 Laravel 애플리케이션에서 단위 및 통합 테스트를 수행합니다.

See all articles