v13.40.0. Zie Databaseconfiguratie voor de basis van verbindingsinstellingen en Package discovery voor het laden van providers.
Kies een uitbreidingspunt
Het aanmaken van databaseverbindingen kent uitbreidingspunten met een verschillend bereik.
De retourwaarde van de callback die je aan
DB::extend() doorgeeft, is geen PDO of Query Builder, maar een Illuminate\Database\Connection. DatabaseManager::configure() vereist deze klasse.
Uitbreidingen op verbindingsnaam gaan voor drivernamen
DatabaseManager::makeConnection() haalt eerst de configuratie op en kiest daarna in de volgende volgorde de aanmaakmethode.
DB::extend('reporting', ...)wordt toegepast opdatabase.connections.reporting.DB::extend('mysql', ...)wordt toegepast op verbindingen metdrivermysqlwaarvoor geen uitbreiding op verbindingsnaam bestaat.- Beide gebruiken hetzelfde uitbreidingsregister. Houd rekening met botsingen tussen verbindingsnamen en drivernamen en gebruik namen die specifiek zijn voor je package.
extend()maakt geen configuratiearray aan. Als je alleen de uitbreiding registreert en er geen verbindingsinstellingen met die naam bestaan, volgt een exception.
Kies een eigen drivernaam expliciet
Het volgende minimale voorbeeld koppelt de eigen naamacme-sqlite aan het aanmaken van een standaard SQLite-verbinding. Het is geen voorbeeld van het implementeren van een nieuw databaseprotocol of SQL-dialect. Het laat de grens zien tussen registreren en selecteren wanneer je een eigen adapter distribueert.
Ervan uitgaande dat Acme\DatabaseBridge\ via Composer-PSR-4 aan src/ is gekoppeld, plaats je dit in src/DatabaseBridgeServiceProvider.php.
db.factory is de binding van de ConnectionFactory die Laravel deelt. Omdat de standaard-Factory rechtstreeks wordt aangeroepen, keer je niet terug naar de uitbreidingsselectie van de DatabaseManager en kun je het uitgestelde aanmaken van de SQLite-PDO en het aanmaken van de Connection hergebruiken.
Deze callback wordt uitgevoerd wanneer de verbinding voor het eerst wordt opgelost. De boot() van de provider registreert alleen de aanmaakmethode en voert geen verbindingstests of migrations uit. Laad hem als gewone, niet-uitgestelde provider, zodat hij geladen is voordat de betreffende verbinding voor het eerst wordt opgelost.
De gebruikende applicatie voegt de verbinding toe aan de bestaande connections-array in config/database.php. De standaardwaarde default wordt niet gewijzigd.
acme_reports, niet de drivernaam acme-sqlite. In het voorbeeld wordt driver omgezet naar sqlite voordat het aan de Factory wordt doorgegeven, dus ook getDriverName() geeft na het aanmaken sqlite terug.
Vervangen door een Connection-subklasse is een ander bereik
Wil je de Connection-klasse van een bestaande driver zelf vervangen, dan is erConnection::resolverFor(). De callback krijgt niet altijd een direct verbonden PDO, maar soms een Closure die de PDO uitgesteld aanmaakt.
Deze registratie wordt echter vastgehouden in een statische property van de Connection-klasse. Registreer je hem voor sqlite, dan heeft dat invloed op alle SQLite-verbindingen die nieuw via de standaard-Factory worden aangemaakt, inclusief het acme-sqlite-voorbeeld hierboven. Je kunt het niet gebruiken als vervanging voor slechts één verbindingsnaam.
- Retourneer in de callback een Connection-subklasse voor de betreffende database. Met alleen de basis-Connection blijven databasespecifieke Grammar, Processor enz. niet behouden.
- De Factory scheidt
createConnector()encreateConnection(). Alleen een registratie metresolverFor()levert nog geen PDO-connector voor een onbekende driver. - Als je eigen resolver van
DB::extend()de standaard-Factory niet gebruikt, wordt ook de controle opresolverFor()binnen de Factory niet doorlopen. - Opnieuw registreren voor dezelfde driver overschrijft de vorige. Controleer conflicten met andere packages en het doorlekken naar tests binnen hetzelfde PHP-proces.
DB::extend() met een eigen verbindingsnaam of drivernaam.
Maak onderscheid tussen reconnect en purge
De DatabaseManager houdt aangemaakte Connections per verbindingsnaam vast. Wijzigingen in de configuratie of resolver worden niet automatisch doorgevoerd in verbindingen die al zijn aangemaakt.
Vooral
reconnect() is geen API die de klasse of configuratiearray van een vastgehouden Connection volledig vervangt. Wil je wijzigingen in de uitbreidingsklasse of verbindingsinstellingen doorvoeren, roep dan op een veilig moment zonder lopende transactie purge() aan en haal daarna een nieuwe verbinding op.
Test het registreren en aanmaken van de package
Met Orchestra Testbench laad je de provider en selecteer je de eigen driver daadwerkelijk. Het volgende is een voorbeeld vantests/DatabaseBridgeTest.php. De uitvoeringsomgeving heeft PDO en de SQLite-driver nodig.
:memory: verloren gaat wanneer de verbinding wordt verbroken, verwacht deze test niet dat tabellen of data behouden blijven. Voeg in een echte package ook het volgende toe.
- Dat de resolver van de verbindingsnaam voorrang heeft op de resolver van de drivernaam.
- Dat opnieuw registreren onder dezelfde naam en
forgetExtension()aangemaakte Connections niet vervangen. - Exceptions bij ontbrekende verplichte instellingen en het gedrag bij een mislukte verbinding.
- De functies die je belooft te ondersteunen, zoals migrations, transacties en read/write-scheiding op ondersteunde databases.
- Dat registraties en verbindingsstatus niet door elkaar raken bij langlevende workers of in combinatie met meerdere packages.
Controlepunten voor onderhoud
- Wordt er met een eigen naam opt-in gewerkt, zonder stilzwijgend de standaardverbinding of ingebouwde drivers te overschrijven?
- Worden er geen Closures of verbindingsobjecten in de configuratiecache gezet, en staat de aanmaaklogica in de provider?
- Worden verbindingsdoelen en inloggegevens beheerd als betrouwbare applicatieconfiguratie?
- Heb je de argumenten van
extend(), de aanmaakvolgorde van de Factory en watreconnect()overneemt opnieuw gecontroleerd voor de ondersteunde Laravel-versies? - Informeer je gebruikers over de procedure voor opnieuw aanmaken na configuratiewijzigingen en het herstarten van workers?
Gerelateerde pagina’s
- Laravel-packages ontwikkelen
- Levensduur van packageservices ontwerpen
- Packageconfiguratie samenvoegen en cachen
- Migrations van packages publiceren en bijwerken
Geraadpleegde primaire bronnen
- Officiële Laravel-documentatie: database en meerdere verbindingen
- Officiële Laravel-documentatie: serviceproviders van packages
- DatabaseManager: aanmaakvolgorde, registratie van uitbreidingen, vasthouden van verbindingen en herverbinden
- ConnectionFactory: uitgesteld aanmaken van PDO en Connection-resolver
- Connection: resolverFor en getResolver
- DatabaseServiceProvider: registratie van db en db.factory