Laravel의 종속성 주입 및 IoC에 대한 자세한 소개(예제 포함)
이 기사는 Laravel의 종속성 주입 및 IoC에 대한 자세한 소개를 제공합니다(예제 포함). 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.
개발자로서 우리는 항상 디자인 패턴을 사용하고 새롭고 강력한 프레임워크를 시도하여 잘 디자인되고 강력한 코드를 작성하는 새로운 방법을 찾으려고 노력하고 있습니다. 이 기사에서는 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
클래스를 직접 사용하지 않고 삽입할 수 있습니다. Connection
类注入而不需要直接使用它。
将组件注入类时,可以使用以下三个选项之一:
构造方法注入
class UserProvider{ protected $connection; public function __construct( Connection $con ){ $this->connection = $con; } ...
Setter 方法注入
同样,我们也可以使用 Setter 方法注入依赖关系:
class UserProvider{ protected $connection; public function __construct(){ ... } public function setConnection( Connection $con ){ $this->connection = $con; } ...
接口注入
interface ConnectionInjector{ public function injectConnection( Connection $con ); } class UserProvider implements ConnectionInjector{ protected $connection; public function __construct(){ ... } public function injectConnection( Connection $con ){ $this->connection = $con; } }
当一个类实现了我们的接口时,我们定义了 injectConnection
方法来解决依赖关系。
优势
现在,当测试我们的类时,我们可以模拟依赖类并将其作为参数传递。每个类必须专注于一个特定的任务,而不应该关心解决它们的依赖性。这样,你将拥有一个更专注和可维护的应用程序。
如果你想了解更多关于 DI 的信息,Alejandro Gervassio 在 本系列 文章中对其进行了广泛而专业的介绍,所以一定要去读这些文章。那么,什么又是 IoC 呢?IoC (控制反转)不需要使用依赖注入,但它可以帮助你有效的管理依赖关系。
控制反转
Ioc 是一个简单的组件,可以更加方便地解析依赖项。你可以将对象形容为容器,并且每次解析类时,都会自动注入依赖项。
Laravel Ioc
当你请求一个对象时, Laravel Ioc 在解决依赖关系的方式上有些特殊:
我们使用一个简单的例子,将在本文中改进它。SimpleAuth
类依赖于 FileSessionStorage
,所以我们的代码可能是这样的:
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();
这是一种经典的方法,让我们从使用构造函数注入开始。
class SimpleAuth{ protected $session; public function __construct( FileSessionStorage $session ){ $this->session = $session; } }
现在我们创建一个对象:
$auth = new SimpleAuth( new FileSessionStorage() );
现在我想使用 Laravel Ioc 来管理这一切。
因为 Application
类继承自 Container
类,所以你可以通过 App
门面来访问容器。
App::bind( 'FileSessionStorage', function(){ return new FileSessionStorage; });
bind
方法第一个参数是要绑定到容器的唯一 ID ,第二个参数是一个回调函数每当执行 FileSessionStorage
类时执行,我们还可以传递一个表示类名的字符串,如下所示。
Note: 如果你查看 Laravel 包时,你将看到绑定有时会分组,比如( view
, view.finder
……)。
假设我们将会话存储转换为 Mysql 存储,我们的类应该类似于:
class MysqlSessionStorage{ public function __construct(){ //... } public function get($key){ // do something } public function set( $key, $value ){ // do something } }
现在我们已经更改了依赖项,我们还需要更改 SimpleAuth
构造函数,并将新对象绑定到容器中!
高级模块不应该依赖于低级模块,两者都应该依赖于抽象对象。
抽象不应该依赖于细节,细节应该取决于抽象。Robert C. Martin
我们的 SimpleAuth
类不应该关心我们的存储是如何完成的,相反它更应该关注于消费的服务。
因此,我们可以抽象实现我们的存储:
interface SessionStorage{ public function get( $key ); public function set( $key, $value ); }
这样我们就可以实现并请求 SessionStorage
接口的实例:
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; } }
如果我们使用 App::make('SimpleAuth')
通过容器解析 SimpleAuth
类,容器将会抛出 BindingResolutionException
,尝试从绑定解析类之后,返回到反射方法并解析所有依赖项。
Uncaught exception 'Illuminate\Container\BindingResolutionException' with message 'Target [SessionStorage] is not instantiable.'
容器正试图将接口实例化。我们可以为该接口做一个具体的绑定。
App:bind( 'SessionStorage', 'MysqlSessionStorage' );
现在每次我们尝试从容器解析该接口时,我们会得到一个 MysqlSessionStorage
생성자 메서드 주입
rrreeeSetter 메서드 주입
🎜마찬가지로 Setter도 사용할 수 있습니다. 종속성을 주입하는 메서드 관계: 🎜rrreee인터페이스 주입
rrreee🎜 클래스가 인터페이스를 구현할 때 종속성을 해결하기 위해injectConnection
메서드를 정의합니다. 🎜장점
🎜이제 클래스를 테스트할 때 종속 클래스를 모의하고 매개변수로 전달할 수 있습니다. 각 클래스는 특정 작업에 집중해야 하며 종속성을 해결하는 데 관심을 가져서는 안 됩니다. 이렇게 하면 더욱 집중적이고 유지 관리가 쉬운 애플리케이션을 갖게 됩니다. 🎜🎜DI에 대해 더 자세히 알고 싶다면 Alejandro Gervassio가 이 기사 시리즈에서 DI에 대해 광범위하고 전문적으로 다루었으니 꼭 읽어보세요. 그렇다면 IoC란 무엇인가? IoC(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🎜컨테이너가 인터페이스를 인스턴스화하려고 합니다. 이 인터페이스에 대해 특정 바인딩을 만들 수 있습니다. 🎜rrreee🎜이제 컨테이너에서 이 인터페이스를 해결하려고 시도할 때마다 MysqlSessionStorage
인스턴스를 얻게 됩니다. 스토리지 서비스를 전환하려면 이 바인딩을 변경하면 됩니다. 🎜참고: 클래스가 컨테이너에 바인딩되었는지 확인하려면 App::bound('ClassName')
을 사용하거나 App:: 아직 등록되지 않은 바인딩을 등록하려면 binIf('ClassName')
을 사용하세요. 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 Ioc은 싱글톤 바인딩을 처리하기 위해 App::singleton('ClassName', 'resolver')
도 제공합니다. App::instance('ClassName', 'instance')
를 사용하여 싱글톤 바인딩을 생성할 수도 있습니다.
컨테이너가 종속성을 해결할 수 없는 경우 ReflectionException
이 발생하지만 App::resolvingAny(Closure)
메서드를 사용하여 콜백 함수의 형태 지정된 유형.
resolvingAny
메서드는 계속 호출되지만 bind
의 반환 값을 직접 반환합니다. > 방법. 🎜팁🎜바인딩 작성 위치:
🎜작은 애플리케이션인 경우 전역 시작 파일 global/ start에 작성할 수 있습니다. .php
이지만 프로젝트 규모가 점점 커질 경우 Service Provider를 사용해야 합니다. 🎜🎜테스트: 🎜빠르고 쉬운 테스트가 필요한 경우 php artisan Tinker
를 사용해 보세요. 이는 매우 강력하며 Laravel 테스트 프로세스를 개선하는 데 도움이 될 수 있습니다. 🎜Reflection API: 🎜PHP의 Reflection API는 매우 강력합니다. Laravel Ioc에 대해 자세히 알고 싶다면 먼저 이 튜토리얼을 읽어 더 많은 정보를 얻을 수 있습니다. [관련 추천: 🎜PHP 비디오 튜토리얼🎜]
위 내용은 Laravel의 종속성 주입 및 IoC에 대한 자세한 소개(예제 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

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

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

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

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

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

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

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

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

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

뜨거운 주제











Laravel은 웹 응용 프로그램을 쉽게 구축하기위한 PHP 프레임 워크입니다. 설치 : Composer를 사용하여 전 세계적으로 Laravel CLI를 설치하고 프로젝트 디렉토리에서 응용 프로그램을 작성하는 등 다양한 기능을 제공합니다. 라우팅 : Routes/Web.php에서 URL과 핸들러 간의 관계를 정의하십시오. 보기 : 리소스/뷰에서보기를 작성하여 응용 프로그램의 인터페이스를 렌더링합니다. 데이터베이스 통합 : MySQL과 같은 데이터베이스와 상자 외 통합을 제공하고 마이그레이션을 사용하여 테이블을 작성하고 수정합니다. 모델 및 컨트롤러 : 모델은 데이터베이스 엔티티를 나타내고 컨트롤러는 HTTP 요청을 처리합니다.

CRAFTCMS를 사용하여 웹 사이트를 개발할 때 특히 CSS 및 JavaScript 파일을 자주 업데이트 할 때 자주 리소스 파일 캐싱 문제가 발생하면 이전 버전의 파일이 여전히 브라우저에서 캐싱 될 수 있으므로 사용자는 최신 변경 사항을 볼 수 없습니다. 이 문제는 사용자 경험에 영향을 줄뿐만 아니라 개발 및 디버깅의 어려움을 증가시킵니다. 최근에 나는 프로젝트에서 비슷한 문제를 겪었고, 약간의 탐색 후 플러그인 Wiejeben/Craft-Laravel-Mix를 발견하여 캐싱 문제를 완벽하게 해결했습니다.

Laravel provides a comprehensive Auth framework for implementing user login functions, including: Defining user models (Eloquent model), creating login forms (Blade template engine), writing login controllers (inheriting Auth\LoginController), verifying login requests (Auth::attempt) Redirecting after login is successful (redirect) considering security factors: hash passwords, anti-CSRF protection, rate limiting and security 헤더. 또한 Auth Framework는 비밀번호 재설정, 이메일 등록 및 확인과 같은 기능도 제공합니다. 자세한 내용은 Laravel 문서를 참조하십시오 : https://laravel.com/doc

여전히 인기있는 것은 사용 편의성, 유연성 및 강력한 생태계입니다. 1) 사용 편의성과 간단한 구문은 초보자에게 첫 번째 선택입니다. 2) 웹 개발, HTTP 요청 및 데이터베이스와의 우수한 상호 작용과 밀접하게 통합되었습니다. 3) 거대한 생태계는 풍부한 도구와 라이브러리를 제공합니다. 4) 활성 커뮤니티와 오픈 소스 자연은 새로운 요구와 기술 동향에 맞게 조정됩니다.

기사 요약 :이 기사는 Laravel 프레임 워크를 쉽게 설치하는 방법에 대한 독자들을 안내하기위한 자세한 단계별 지침을 제공합니다. Laravel은 웹 애플리케이션의 개발 프로세스를 가속화하는 강력한 PHP 프레임 워크입니다. 이 자습서는 시스템 요구 사항에서 데이터베이스 구성 및 라우팅 설정에 이르기까지 설치 프로세스를 다룹니다. 이러한 단계를 수행함으로써 독자들은 라벨 프로젝트를위한 탄탄한 토대를 빠르고 효율적으로 놓을 수 있습니다.

Laravel 프레임 워크에는 개발자의 다양한 요구를 충족시키기 위해 버전 번호를 쉽게 볼 수있는 내장 방법이 있습니다. 이 기사는 Composer Command Line 도구 사용, .env 파일에 액세스하거나 PHP 코드를 통해 버전 정보를 얻는 것을 포함하여 이러한 방법을 탐색합니다. 이러한 방법은 Laravel 애플리케이션의 버전 관리를 유지 관리하고 관리하는 데 필수적입니다.

Laravel 프레임 워크를 배우고 싶지만 자원이나 경제적 압력이 없습니까? 이 기사는 Laravel의 무료 학습을 제공하며 온라인 플랫폼, 문서 및 커뮤니티 포럼과 같은 리소스를 사용하여 PHP 개발 여정을 시작하는 것에서 마스터까지의 탄탄한 토대를 마련하는 방법을 가르쳐줍니다.

초보자를위한 Laravel Framework 버전 선택 안내서 에서이 기사는 초보자가 많은 버전 중에서 정보에 입각 한 선택을하는 데 도움이되도록 설계된 Laravel의 버전 차이점으로 뛰어 들었습니다. 우리는 각 릴리스의 주요 기능에 중점을두고 장단점을 비교하며 초보자가 기술 수준 및 프로젝트 요구 사항에 따라 가장 적합한 Laravel 버전을 선택할 수 있도록 유용한 조언을 제공 할 것입니다. 초보자에게는 적절한 버전의 Laravel을 선택하는 것이 학습 곡선과 전반적인 개발 경험에 크게 영향을 줄 수 있기 때문에 중요합니다.
