메인 콘텐츠로 건너뛰기
패키지에서 데이터베이스 연결을 확장하려면 생성 방법의 등록과 사용할 연결의 선택을 분리합니다. 설치만으로 애플리케이션의 기본 연결이나 모든 MySQL 연결이 대체되지 않도록 설계합니다. 이 페이지는 Laravel Framework v13.40.0의 공식 구현을 확인한 내용입니다. 연결 설정의 기본은 데이터베이스 설정을, 프로바이더의 로드는 패키지 자동 검출을 참조하세요.

확장 지점 선택하기

데이터베이스 생성 처리에는 적용 범위가 서로 다른 확장 지점이 있습니다. DB::extend()에 전달하는 콜백의 반환값은 PDO나 Query Builder가 아니라 Illuminate\Database\Connection입니다. DatabaseManager::configure()가 이 클래스를 요구합니다.
데이터베이스의 extend()는 공통 Illuminate\Support\Manager와 같은 호출 규약이 아닙니다. 콜백의 첫 번째 인수는 애플리케이션 컨테이너가 아니라 연결 설정 배열입니다. 다른 드라이버 확장의 예시를 그대로 가져다 쓰지 마세요.

연결 이름의 확장이 드라이버 이름보다 우선한다

DatabaseManager::makeConnection()은 설정을 가져온 뒤 다음 순서로 생성 방법을 선택합니다.
  • DB::extend('reporting', ...)는 database.connections.reporting에 적용됩니다.
  • DB::extend('mysql', ...)는 연결 이름 쪽에 확장이 없고 driver가 mysql인 연결에 적용됩니다.
  • 둘 다 같은 확장 레지스트리를 사용합니다. 연결 이름과 드라이버 이름의 충돌도 고려해 패키지 고유의 이름을 사용합니다.
  • extend()는 설정 배열을 만들지 않습니다. 확장만 등록하고 지정한 이름의 연결 설정이 없으면 예외가 발생합니다.

독자 드라이버 이름을 명시적으로 선택하기

다음은 독자 이름 acme-sqlite를 표준 SQLite 연결 생성으로 연결하는 최소 예시입니다. 새로운 DB 프로토콜이나 SQL 방언을 구현하는 예시가 아닙니다. 독자 어댑터를 배포할 때의 등록과 선택의 경계를 보여 줍니다. Acme\DatabaseBridge\가 Composer의 PSR-4로 src/에 대응하는 구성을 가정하고, src/DatabaseBridgeServiceProvider.php에 배치합니다.
db.factory는 Laravel이 공유하는 ConnectionFactory의 바인딩입니다. 표준 Factory를 직접 호출하므로 DatabaseManager의 확장 선택으로 되돌아가지 않고, SQLite의 지연 PDO 생성과 Connection 생성을 재사용할 수 있습니다. 이 콜백은 처음 연결을 해석할 때 실행됩니다. 프로바이더의 boot()는 생성 방법의 등록만 수행하며, 연결 테스트나 마이그레이션을 실행하지 않습니다. 일반적인 비지연 프로바이더로서 대상 연결이 처음 해석되기 전에 로드되도록 합니다. 사용하는 애플리케이션은 config/database.php의 기존 connections 배열에 연결을 추가합니다. 기본값인 default는 변경하지 않습니다.
SQLite 파일을 미리 준비하고 쓰기 권한을 확인한 뒤 사용합니다. 패키지를 로드하기만 해도 파일이 생성되는 설계로 만들지 않습니다.
사용자가 전달하는 것은 연결 이름 acme_reports이며, 드라이버 이름 acme-sqlite가 아닙니다. 예시에서는 Factory에 전달하기 전에 driver를 sqlite로 변환하므로, 생성 후의 getDriverName()도 sqlite입니다.
resolver 안에서 DB::connection($name)을 다시 호출하면 아직 보관되지 않은 같은 연결의 생성으로 되돌아갑니다. 재귀를 피하려면 Factory나 독자 어댑터로 Connection을 생성합니다.

Connection 서브클래스로의 대체는 별개의 범위

기존 드라이버의 Connection 클래스 자체를 대체하려면 Connection::resolverFor()가 있습니다. 콜백에는 즉시 연결된 PDO가 아니라 PDO를 지연 생성하는 Closure가 전달되는 경우도 있습니다. 다만 이 등록은 Connection 클래스의 static 프로퍼티에 보관됩니다. sqlite에 등록하면 표준 Factory로 새로 만드는 SQLite 연결 전체에 영향을 주며, 위의 acme-sqlite 예시도 대상이 됩니다. 연결 이름 하나만 대체하는 용도로는 다룰 수 없습니다.
  • 콜백에서는 대상 DB용 Connection 서브클래스를 반환합니다. 기본 Connection만으로는 DB 고유의 Grammar나 Processor 등을 유지할 수 없습니다.
  • Factory는 createConnector()와 createConnection()을 분리하고 있습니다. resolverFor()를 등록하는 것만으로 알 수 없는 드라이버의 PDO 커넥터까지 제공되는 것은 아닙니다.
  • DB::extend()의 독자 resolver가 표준 Factory를 사용하지 않으면, Factory 내부의 resolverFor() 확인도 거치지 않습니다.
  • 같은 드라이버에 다시 등록하면 덮어씁니다. 다른 패키지와의 충돌과, 같은 PHP 프로세스 내 테스트로의 이월을 확인합니다.
영향을 제한하고 싶은 패키지는 먼저 고유한 연결 이름·드라이버 이름을 사용한 DB::extend()를 검토합니다.

reconnect와 purge 구분하기

DatabaseManager는 생성된 Connection을 연결 이름별로 보관합니다. 설정이나 resolver를 변경해도 이미 생성된 연결에는 자동으로 반영되지 않습니다. 특히 reconnect()는 보관된 Connection의 클래스나 설정 배열을 통째로 대체하는 API가 아닙니다. 확장 클래스나 연결 설정의 변경을 반영하려면, 진행 중인 트랜잭션이 없는 안전한 시점에 purge()한 뒤 새 연결을 가져옵니다.
purge()는 다른 서비스나 변수가 보관하고 있는 Connection 참조를 새것으로 교체하지 않습니다. 또한 연결 이름의 ::read·::write·::direct는 별도의 보관 키가 되므로, 기본 이름을 purge하는 것만으로 이들까지 일괄 삭제된다고 생각하지 마세요.테넌트 전환 등을 목적으로 실행 중인 공유 연결 설정을 함부로 바꾸지 마세요. 장기 실행 워커에서는 설정 캐시의 갱신뿐 아니라 프로세스 재시작과 보관된 서비스에 미치는 영향도 확인합니다.

패키지의 등록과 생성 테스트하기

Orchestra Testbench에서는 프로바이더를 로드하고 독자 드라이버를 실제로 선택합니다. 다음은 tests/DatabaseBridgeTest.php의 예시입니다. 실행 환경에는 PDO와 SQLite 드라이버가 필요합니다.
:memory:는 연결이 끊기면 내용이 사라지므로, 이 테스트는 테이블이나 데이터의 유지를 기대하지 않습니다. 실제 패키지에서는 다음도 추가합니다.
  • 연결 이름의 resolver가 드라이버 이름의 resolver보다 우선하는지.
  • 같은 이름의 재등록과 forgetExtension()이 생성된 Connection을 대체하지 않는지.
  • 필수 설정이 빠졌을 때의 예외와 연결 실패 시의 동작.
  • 지원 DB에서의 마이그레이션, 트랜잭션, read/write 분리 등 제공을 약속하는 기능.
  • 장기 실행 워커나 여러 패키지와 함께 사용할 때 등록이나 연결 상태가 섞이지 않는지.

유지보수 시 확인 항목

  • 독자 이름으로 옵트인하며, 기본 연결이나 내장 드라이버를 몰래 덮어쓰고 있지 않은가.
  • config 캐시에 Closure나 연결 객체를 넣지 않고, 생성 처리를 프로바이더에 두고 있는가.
  • 연결 대상과 인증 정보를 신뢰할 수 있는 애플리케이션 설정으로 관리하고 있는가.
  • extend()의 인수, Factory의 생성 순서, reconnect()의 전달 대상을 지원 대상 Laravel에서 다시 확인했는가.
  • 설정 변경 후의 재생성 절차와 워커 재시작을 사용자에게 안내하고 있는가.

관련 페이지

참조한 1차 정보

마지막 수정일 2026년 11월 3일