Skip to main content
Wie een package met een database langdurig onderhoudt, heeft niet alleen een procedure nodig voor de eerste installatie, maar ook een manier om wijzigingen bij gebruikers te krijgen bij wie de tabellen al bestaan. Ontwerp het publiceren, het uitvoeren en de uitvoeringsgeschiedenis van migrations als afzonderlijke processen. Deze pagina bouwt voort op Laravel-packages ontwikkelen en analyseert ServiceProvider, VendorPublishCommand en Migrator in Laravel 13. Voor de implementatie van het framework is v13.34.0 als referentie gebruikt.

Kopiëren en overdragen, of laden vanuit het package?

publishesMigrations() registreert alleen de bron en de bestemming als te publiceren items. Het booten van de provider kopieert geen bestanden en voert geen SQL uit. loadMigrationsFrom() registreert daarentegen een zoekpad bij de Migrator. Een gewone migrate neemt dan ook de bestanden in dat pad mee, maar alleen het booten van de provider voert ze niet uit. Als gebruikers vóór het uitvoeren tabelnamen of kolommen moeten kunnen aanpassen, ligt de publicatiemethode voor de hand. Beheert het package het schema zelf en verwacht je niet dat gebruikers de bestanden bewerken, dan kun je ook de methode met direct laden overwegen. De twee providervoorbeelden hieronder zijn alternatieven voor elkaar.
Vermijd een ontwerp waarin dezelfde migrations zowel worden gepubliceerd als direct geladen. Als de timestamp bij het publiceren verandert, worden bron en bestemming als afzonderlijke items in de uitvoeringsgeschiedenis behandeld, waardoor dezelfde tabel mogelijk twee keer wordt aangemaakt.

De publicatiemethode implementeren

Geef een package-specifieke tag op, zodat gebruikers deze resources los van andere resources kunnen publiceren.
Bij de eerste installatie kopieer je de bestanden door de provider en de tag op te geven, controleer je de inhoud en voer je ze daarna uit. Geef je beide op, dan kiest Laravel de te publiceren items met die tag die bij die provider horen.

Het aanpassen van timestamps hangt af van een instelling

De officiële documentatie beschrijft dat de timestamps van migrations bij het publiceren worden bijgewerkt naar de huidige datum en tijd. In de implementatie van ServiceProvider::publishesMigrations() wordt de bron echter alleen aan de items voor timestampaanpassing toegevoegd als database.migrations.update_date_on_publish is ingeschakeld. De fallback bij het ophalen van deze instelling is false. De standaardapplicatie van Laravel 13 bevat in config/database.php de volgende instelling. Controleer bij applicaties die een oudere structuur hebben overgenomen ook of deze instelling bestaat.
Daarnaast herschrijft VendorPublishCommand de datum en tijd als het bestand overeenkomt met het werkelijke pad van een geregistreerde bron en de bestemmingsnaam het formaat YYYY_MM_DD_HHMMSS_ bevat. Uitgaande van het starttijdstip van het commando wordt per bestand één seconde opgeteld. Bevat de naam dit formaat niet, dan voegt deze stap geen datum en tijd toe.
De datum en tijd na publicatie hierboven dienen alleen ter illustratie. De werkelijke bestandsnaam hangt af van het moment waarop je publiceert.
Het bijwerken van timestamps hangt af van zowel de registratie in het package als de instellingen van de applicatie die het gebruikt. Wijzig deze instelling niet zomaar vanuit de provider van het package, maar beschrijf de voorwaarde in de installatie-instructies. Gebruik je een configuratiecache, dan moet die na het wijzigen van de instelling ook opnieuw worden opgebouwd.

Opnieuw publiceren is niet “alleen niet-uitgevoerde bestanden toevoegen”

vendor:publish controleert de uitvoeringsgeschiedenis in de database niet. Bovendien controleert de kopieerstap in v13.34.0 op bestaande bestanden aan de hand van de bestemming vóór de timestampaanpassing. Ook bij het publiceren van een map wordt eerst gecontroleerd of hetzelfde relatieve pad als de bron al op de bestemming bestaat, en pas daarna worden datum en tijd herschreven. Als de datum en tijd bij de eerste publicatie zijn veranderd en er in de applicatie geen bestand met dezelfde naam als de bron staat, kan het opnieuw publiceren van dezelfde tag dus een bestand met een andere datum en tijd toevoegen. Ga er niet van uit dat je duplicaten altijd voorkomt door --force weg te laten.

Of iets is uitgevoerd, wordt bepaald aan de hand van de bestandsnaam

Migrator::getMigrationName() geeft de basisnaam van het bestand zonder .php terug. Om te bepalen of een migration nog niet is uitgevoerd, wordt deze naam vergeleken met de uitvoeringsgeschiedenis. Of de PHP-inhoud of de tabelnaam hetzelfde is, speelt bij deze beoordeling geen rol.
Dit zijn twee verschillende migrationnamen. Ook als de eerste al is uitgevoerd, geldt de tweede op basis van die geschiedenis niet als uitgevoerd.
Voer bij elke package-update niet zonder meer het publicatiecommando voor de eerste installatie opnieuw uit, en maak --force geen standaardstap. Dat kan niet alleen wijzigingen in gepubliceerde bestanden overschrijven, maar door de timestampaanpassing ook dubbele bewerkingen toevoegen.

De methode met direct laden implementeren

Als je de migrations in het package direct wilt laten uitvoeren, registreer je een zoekpad. Bij deze methode voeg je geen stap toe om dezelfde bestanden te publiceren.
loadMigrationsFrom() roept path() aan zodra de Migrator wordt geresolved. Migrator::path() verwijdert dubbele zoekpaden, en getMigrationFiles() gebruikt de migrationnaam als sleutel voor de gevonden bestanden en sorteert ze op die naam. Wanneer een gebruiker het package bijwerkt, worden nieuwe bestanden bij de volgende migrate meegenomen. Wijzig de namen van bestaande bestanden niet en voeg voor nieuwe schemawijzigingen nieuwe bestanden toe. Neem ook de naam van de functionaliteit op, zoals in create_courier_deliveries_table, om conflicten met andere packages te voorkomen. Bestanden met dezelfde naam krijgen dezelfde sleutel; ze worden niet allebei onafhankelijk uitgevoerd.
Overstappen van de publicatiemethode naar direct laden is niet zomaar een kwestie van de provider herschrijven. Als de uitvoeringsgeschiedenis van gebruikers is vastgelegd onder de namen van het moment van publicatie, komen die niet overeen met de oorspronkelijke namen in het package. Je hebt een migratieplan nodig dat rekening houdt met de geschiedenis, de gepubliceerde bestanden en rollbacks van bestaande gebruikers.

Schemawijzigingen bij bestaande gebruikers krijgen

Wil je bijvoorbeeld een trackingnummer aan de bezorgtabel toevoegen, bewerk dan niet de al gepubliceerde create_courier_deliveries_table, maar voeg een nieuw bestand voor de wijziging toe. Als je een bestaande aanmaak-migration bewerkt, wordt die wijziging bij gebruikers die hem al hebben uitgevoerd niet doorgevoerd.
database/migrations/2026_10_02_000000_add_tracking_code_to_courier_deliveries_table.php
Omdat dit voorbeeld een kolom toevoegt aan een tabel met bestaande rijen, is de kolom hier nullable. Moet de kolom verplicht worden of moeten gegevens worden aangevuld, ontwerp die stappen en de uitvoeringsvolgorde dan apart. Bij de publicatiemethode bied je een updateprocedure die de gepubliceerde bestanden van de gebruiker vergelijkt en alleen de nu toegevoegde bestanden levert. Je kunt ook een aparte publicatietag voor nieuwe bestanden aanmaken, maar als timestampaanpassing is ingeschakeld, geldt voor het herhaald uitvoeren van die tag dezelfde waarschuwing. Maak van de updateprocedure niet simpelweg het opnieuw uitvoeren van de tag voor de eerste installatie. Bij direct laden detecteert de bijgewerkte code de nieuwe bestanden. Bij beide methoden verandert de database niet alleen doordat de bestanden bestaan, dus vermeld in de release notes dat migrations moeten worden uitgevoerd.

Wat je vóór een release controleert

Controleer naast de databasetests van het package ook de publicatie- en updateprocedure in een applicatie die het package gebruikt. Alleen migrations direct laden in tests betekent niet dat je de publicatiemethode, waarbij bestandsnamen veranderen, hebt gevalideerd.
  • Een eerste installatie op een lege database maakt de benodigde tabellen aan.
  • Bij een update vanaf de database en uitvoeringsgeschiedenis van een oudere release worden alleen de nieuwe wijzigingen toegepast.
  • Je hebt de bestandslijst bekeken na het herhaald uitvoeren van hetzelfde publicatiecommando, en de updateprocedure veroorzaakt geen duplicaten.
  • De procedure houdt rekening met in- of uitgeschakelde timestampaanpassing en met bewerkte gepubliceerde bestanden.
  • Je hebt de rollback van nieuwe migrations en de uitvoeringsvolgorde ten opzichte van de andere migrations van de applicatie gecontroleerd.

Gerelateerde pagina’s

Migrations

Bekijk de basis van schemadefinities, uitvoeringsgeschiedenis en rollbacks.

Packages testen

Test de service provider en de database van je package.

Packageconfiguratie samenvoegen en cachen

Bekijk updateprocedures die rekening houden met gebruikersinstellingen en de configuratiecache.

Versiecompatibiliteit beheren

Koppel updateprocedures en compatibiliteitswijzigingen aan je releasebeleid.

Geraadpleegde primaire bronnen

Laatst gewijzigd op 2 oktober 2026