Laravel의 종속성 주입 및 IoC
종속성 주입
종속성 주입은 민첩한 아키텍처의 핵심 요소입니다.
예를 살펴보겠습니다.할 수 있습니다. 세 가지 옵션 중 하나를 사용하여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 包时,你将看到绑定有时会分组,比如( view
, view.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
类,容器将会抛出 BindingResolutionException
Setter 메서드 주입
마찬가지로 우리는 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

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

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

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

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

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

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

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

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

뜨거운 주제









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

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

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

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

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

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

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

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