Eine Erweiterung für die Verwendung von Laravel in einer Umgebung mit mehreren Domänen

Dieses Paket ermöglicht die Arbeit einer einzelnen Laravel-Installation mit mehreren HTTP-Domänen.
Es gibt viele Fälle, in denen verschiedene Kunden dieselbe Anwendung in Bezug auf den Code verwenden, nicht jedoch in Bezug auf Datenbank, Speicherung und Konfiguration.
Dieses Paket bietet eine sehr einfache Möglichkeit, für jeden dieser Kunden eine bestimmte Umgebungsdatei, einen bestimmten Speicherpfad und eine bestimmte Datenbank abzurufen.
| Laravel | Multidomain |
|---|---|
| 11.x | 11.x |
| 10.x | 10.x |
| 9.x | 5.x |
| 8.x | 4.x |
| 7.x | 3.x |
| 6.x | 2.x |
| 5.8.x | 1.4.x |
| 5.7.x | 1.3.x |
| 5.6.x | 1.2.x |
| 5.5.x | 1.1.x |
Veröffentlichungen v1.1.x:
Bisher sind die Versionen v1.1.6+, v1.2.x, v1.3.x, v1.4.x, v2.x und v3.x funktional gleichwertig. Die Releases wurden getrennt, um Integrationstests mit der entsprechenden Version des Laravel-Frameworks durchzuführen.
Mit der Veröffentlichung von Laravel 8 sind jedoch die Versionen v1.1.14, v1.2.8, v1.3.8 und v1.4.8 die letzten Versionen, die neue Funktionen für die entsprechenden Laravel 5.x-Versionen enthalten (die Bugfix-Unterstützung ist für diese Versionen weiterhin aktiv). . 13.02.2021 UPDATE : Einige letzte Funktionen für Versionen ab Version 1.1 sind noch in Arbeit :)
v1.0 erfordert Laravel 5.1, 5.2, 5.3 und 5.4 (wird im Vergleich zu Laravel 5.4 nicht mehr gewartet und nicht getestet, die Verwendung des Pakets ist jedoch dieselbe wie für 1.1)
20.02.2023 UPDATE : Ab Laravel 10.x folgen die Paketversionen der gleichen Nummerierung.
Fügen Sie „gecche/laravel-multidomain“ als Anforderung zu „composer.json“ hinzu:
{
"require" : {
"gecche/laravel-multidomain" : "11.*"
}
}Aktualisieren Sie Ihre Pakete mit Composer Update oder installieren Sie sie mit Composer Install.
Sie können das Paket auch mit composer require gecche/laravel-multidomain hinzufügen und später die gewünschte Version angeben.
Dieses Paket muss die Erkennung der HTTP-Domäne in einem minimalen Satz von Laravel-Kernfunktionen gleich zu Beginn des Bootstrap-Prozesses überschreiben, um die spezifische Umgebungsdatei abzurufen. Daher benötigt dieses Paket ein paar weitere Konfigurationsschritte als die meisten Laravel-Pakete.
Installationsschritte:
bootstrap/app.php ändern. //use Illuminate F oundation A pplication
use Gecche Multidomain Foundation ApplicationQueueServiceProvider mit dem erweiterten in der Datei config/app.php wie folgt: ' providers ' => Illuminate Support ServiceProvider:: defaultProviders ()-> merge ([
// Package Service Providers . . .
])-> replace ([
Illuminate Queue QueueServiceProvider::class => Gecche Multidomain Queue QueueServiceProvider::class,
])-> merge ([
// Added Service Providers ( Do not remove this line ) . . .
])-> toArray (), Bitte beachten Sie, dass, wenn Sie die Datei config/app.php aus anderen Gründen geändert haben, wahrscheinlich bereits der oben genannte providers Eintrag in dieser Datei vorhanden ist und die einzige wichtige Zeile diejenige ist, die den QueueServiceProvider ersetzt.
php artisan vendor:publish
(Dieses Paket nutzt die Erkennungsfunktion.)
Wenn Sie die oben genannten Schritte ausführen, erkennt Ihre Anwendung die HTTP-Domäne, in der sie ausgeführt wird, sowohl für HTTP- als auch für CLI-Anfragen, einschließlich Warteschlangenunterstützung.
HINWEIS: In Laravel 11 ist die Installation einfacher als zuvor: Wenn Sie eine frühere Version von Laravel verwenden, überprüfen Sie bitte die Installationsschritte in der Dokumentation.
Das Paket ist dank Community-Beiträgen mit Horizon kompatibel. Wenn Sie dieses Paket zusammen mit Horizon verwenden müssen, müssen Sie zwei weitere Installationsschritte ausführen:
Installieren Sie Laravel Horizon wie gewohnt
Ersetzen Sie den Laravel Horizon-Import ganz oben in der Datei app/Providers/HorizonServiceProvider.php.
//use Laravel H orizon H orizonApplicationServiceProvider ;
use Gecche Multidomain Horizon HorizonApplicationServiceProvider ;Dieses Paket fügt drei Befehle zum Verwalten Ihrer Anwendungs-HTTP-Domänen hinzu:
domain.add artisan-Befehl Der Hauptbefehl ist der Befehl domain:add , der als Argument den Namen der HTTP-Domäne verwendet, die der Anwendung hinzugefügt werden soll. Nehmen wir an, wir haben zwei Domänen, site1.com und site2.com , die denselben Code teilen.
Wir machen einfach:
php artisan domain:add site1.com
Und
php artisan domain:add site2.com
Diese Befehle erstellen zwei neue Umgebungsdateien, .env.site1.com und .env.site2.com , in die Sie die spezifische Konfiguration für jede Site einfügen können (z. B. Datenbankkonfiguration, Cache-Konfiguration und andere Konfigurationen, wie sie normalerweise in einer Umgebung zu finden sind). Datei).
Der Befehl fügt außerdem einen Eintrag im domains in der Datei config/domains.php hinzu.
Darüber hinaus werden zwei neue Ordner erstellt, storage/site1_com/ und storage/site2_com/ . Sie haben die gleiche Ordnerstruktur wie der Hauptspeicher.
Anpassungen an dieser storage müssen mit Werten in der Datei config/domain.php übereinstimmen.
domain.remove artisan-Befehl Der Befehl domain:remove entfernt die angegebene HTTP-Domäne aus der Anwendung, indem er ihre Umgebungsdatei löscht. Z.B:
php artisan domain:remove site2.com
Durch das Hinzufügen der force -Option wird der Domänenspeicherordner gelöscht.
Der Befehl entfernt auch den entsprechenden Eintrag aus dem domains in der Datei config/domains.php .
domain.update_env artisan-Befehl Der Befehl domain:update_env übergibt ein JSON-codiertes Datenarray, um eine oder alle Umgebungsdateien zu aktualisieren. Diese Werte werden am Ende der entsprechenden .env hinzugefügt.
Aktualisieren Sie eine einzelne Domänenumgebungsdatei, indem Sie das domain hinzufügen.
Wenn das domain fehlt, aktualisiert der Befehl alle Umgebungsdateien, einschließlich der Standard .env Datei.
Die Liste der zu aktualisierenden Domänen wird in der Konfigurationsdatei domain.php verwaltet.
Z.B:
php artisan domain:update_env --domain_values='{"TOM_DRIVER":"TOMMY"}'
fügt die Zeile TOM_DRIVER=TOMMY zu allen Domänenumgebungsdateien hinzu.
domain.list artisan-Befehl Der Befehl domain:list listet die aktuell installierten Domänen mit ihrer .env-Datei und dem Speicherpfadverzeichnis auf.
Die Liste wird im domains der Konfigurationsdatei config/domain.php verwaltet.
Diese Liste wird bei jeder Ausführung der Befehle domain:add und domain:remove automatisch aktualisiert.
config:cache artisan-BefehlDer config:cache artisan-Befehl kann mit diesem Paket auf die gleiche Weise wie jeder andere artisan-Befehl verwendet werden.
Beachten Sie, dass dieser Befehl eine Datei config.php für jede Domain generiert, unter der der Befehl ausgeführt wurde. Also der Befehl
php artisan config:cache --domain=site2.com
generiert die Datei
config-site2_com.php
Zur Laufzeit wird die aktuelle HTTP-Domäne im Laravel-Container verwaltet und kann über die von diesem Paket hinzugefügte Methode domain() aufgerufen werden.
Eine domainList() Methode ist verfügbar. Es gibt ein assoziatives Array zurück, das die Informationen zu den installierten Domänen enthält, ähnlich dem obigen Befehl domain.list .
Z.B
[
site1.com => [
'storage_path' => <LARAVEL-STORAGE-PATH>/site1_com,
'env' => '.env.site1.com'
]
]
Für jede von der Anwendung empfangene HTTP-Anfrage wird die spezifische Umgebungsdatei geladen und der spezifische Speicherordner verwendet.
Wenn keine bestimmte Umgebungsdatei und/oder kein Speicherordner gefunden wird, wird die Standarddatei verwendet.
Die Erkennung der richtigen HTTP-Domäne erfolgt mithilfe der PHP-Variable $_SERVER['SERVER_NAME'] .
WICHTIGER HINWEIS: In einigen Ausführungsumgebungen wird $_SERVER['SERVER_NAME'] nicht instanziiert, daher funktioniert dieses Paket nicht ordnungsgemäß, bis Sie die Erkennung von HTTP-Domänen wie unten beschrieben anpassen.
Ab Version 1.1.15 kann die Erkennung von HTTP-Domänen angepasst werden, indem ein Closure als domain_detection_function_web Eintrag des neuen domainParams Arguments des Application -Konstruktors übergeben wird. Im folgenden Beispiel basiert die HTTP-Domänenerkennung auf $_SERVER['HTTP_HOST'] anstelle von $_SERVER['SERVER_NAME'] .
//use Illuminate F oundation A pplication ;
use Gecche Multidomain Foundation Application ;
use Illuminate Foundation Configuration Exceptions ;
use Illuminate Foundation Configuration Middleware ;
$ environmentPath = null ;
$ domainParams = [
' domain_detection_function_web ' => function () {
return Illuminate Support Arr:: get ( $ _SERVER , ' HTTP_HOST ' );
}
];
return Application:: configure (basePath: dirname ( __DIR__ ),
environmentPath: $ environmentPath ,
domainParams: $ domainParams )
-> withRouting (
web: __DIR__ . ' /../routes/web.php ' ,
commands: __DIR__ . ' /../routes/console.php ' ,
health: ' /up ' ,
)
-> withMiddleware ( function ( Middleware $ middleware ) {
//
})
-> withExceptions ( function ( Exceptions $ exceptions ) {
//
})-> create (); Um zwischen Domänen zu unterscheiden, akzeptiert jeder Handwerkerbefehl eine neue Option: domain . Z.B:
php artisan list --domain=site1.com
Der Befehl verwendet die entsprechenden Domäneneinstellungen.
Die Handwerkerbefehle queue:work und queue:listen wurden aktualisiert, um eine neue domain zu akzeptieren.
php artisan queue:work --domain=site1.com
Wie üblich verwendet der obige Befehl die entsprechenden Domäneneinstellungen.
Denken Sie daran, dass Sie, wenn Sie beispielsweise den database verwenden und zwei Domänen haben, die sich dieselbe Datenbank teilen, zwei unterschiedliche Warteschlangen verwenden sollten, wenn Sie die Jobs jeder Domäne separat verwalten möchten.
Sie könnten zum Beispiel:
QUEUE_DEFAULT=default1 für site1.com und QUEUE_DEFAULT=default2 für site2.comqueue.php , indem Sie die Standardwarteschlange entsprechend ändern: 'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => env('QUEUE_DEFAULT','default'),
'retry_after' => 90,
],
php artisan queue:work --domain=site1.com --queue=default1
Und
php artisan queue:work --domain=site1.com --queue=default2
Dasselbe kann natürlich auch für jeden anderen Warteschlangentreiber durchgeführt werden, mit Ausnahme des sync .
storage:link Befehl Wenn Sie den Befehl storage:link verwenden und für jede Domäne einen eigenen symbolischen Link wünschen, müssen Sie diese manuell erstellen, da ein solcher Befehl bisher immer einen Link mit dem Namen storage erstellt und dieser Name im Befehl fest codiert ist. Die Erweiterung des Befehls storage:link die die Auswahl des Namens ermöglicht, liegt außerhalb des Rahmens dieses Pakets (und ich hoffe, dass dies direkt in zukünftigen Versionen von Laravel erfolgen wird).
Eine Möglichkeit, mehrere Speicherlinks zu erhalten, könnte wie folgt aussehen. Nehmen wir an, wir haben zwei Domänen, nämlich site1.com und site2.com mit den zugehörigen Speicherordnern storage/site1_com und storage/site2_com .
ln -s storage/site1_com/app/public public/storage-site1_com
ln -s storage/site2_com/app/public public/storage-site2_com
.env.site1.com und .env.site2.com fügen wir einen Eintrag hinzu, z. B. für die erste Domain: APP_PUBLIC_STORAGE=-site1_com
filesystems.php ändern wir Folgendes: 'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage'.env('APP_PUBLIC_STORAGE'),
'visibility' => 'public',
],
Wenn Sie das Paket außerdem in einer Single Page Application (SPA)-Einstellung verwenden, können Sie unterschiedliche öffentliche Ressourcen für jede Domain besser über .htaccess oder ähnliche Lösungen verwalten, wie Scaenicus in seiner .htaccess-Lösung dargelegt hat.
Ab Version 1.1.11 wurde dem Anwendungskonstruktor ein zweites Argument hinzugefügt, um den Ordner auszuwählen, in dem die Umgebungsdateien abgelegt werden sollen: Wenn Sie Dutzende von Domänen haben, ist es nicht sehr angenehm, Umgebungsdateien in der Root-App von Laravel zu haben Ordner.
Wenn Sie also einen anderen Ordner verwenden möchten, fügen Sie ihn einfach ganz oben in der Datei bootstrap/app.php hinzu. Wenn Sie beispielsweise Umgebungsdateien zum Unterordner envs hinzufügen möchten, gehen Sie einfach wie folgt vor:
//use Illuminate F oundation A pplication ;
use Gecche Multidomain Foundation Application ;
use Illuminate Foundation Configuration Exceptions ;
use Illuminate Foundation Configuration Middleware ;
$ environmentPath = dirname ( __DIR__ ) . DIRECTORY_SEPARATOR . ' envs ' ;
$ domainParams = [];
return Application:: configure (basePath: dirname ( __DIR__ ),
environmentPath: $ environmentPath ,
domainParams: $ domainParams )
-> withRouting (
web: __DIR__ . ' /../routes/web.php ' ,
commands: __DIR__ . ' /../routes/console.php ' ,
health: ' /up ' ,
)
-> withMiddleware ( function ( Middleware $ middleware ) {
//
})
-> withExceptions ( function ( Exceptions $ exceptions ) {
//
})-> create (); Wenn Sie das zweite Argument nicht angeben, wird der Standardordner angenommen. Bitte beachten Sie, dass bei Angabe eines Ordners auch die Standard .env Datei darin abgelegt werden muss
Wenn Sie versuchen, eine Webseite oder einen Shell-Befehl unter einer bestimmten Domäne auszuführen, z. B. sub1.site1.com , und es keine spezifische Umgebungsdatei für diese Domäne gibt, z. B. die Datei .env.sub1.site1.com nicht existiert, wird die Das Paket verwendet die erste verfügbare Umgebungsdatei, indem es den Domänennamen durch Punkte aufteilt. In diesem Beispiel sucht das Paket nach der ersten Umgebungsdatei unter den folgenden:
.env.site1.com
.env.com
.env
Die gleiche Logik gilt auch für den Speicherordner.
Wenn Sie in Ihrer Einstellung den Scheduler von Laravel verwenden, denken Sie daran, dass auch der Befehl schedule:run mit der Domain-Option gestartet werden muss. Daher müssen Sie für jede Domäne einen Planer starten. Zunächst könnte man denken, dass eine Scheduler-Instanz die für jede Domäne gestarteten Befehle verarbeiten sollte, aber der Scheduler selbst wird in einer Laravel-Anwendung ausgeführt, sodass die „Umgebung“, unter der er ausgeführt wird, automatisch auf jeden geplanten Befehl angewendet wird und die --domain -Option hat überhaupt keine Auswirkung.
Das Gleiche gilt für externe Tools wie Supervisor: Wenn Sie Supervisor für handwerkliche Befehle verwenden, z. B. den Befehl queue:work , stellen Sie bitte sicher, dass Sie für jede Domäne, die Sie bearbeiten möchten, einen Befehl vorbereiten.
Aus den oben genannten Gründen gibt es einige Fälle, in denen das Paket nicht funktionieren kann: in den Einstellungen, in denen Sie nicht die Möglichkeit haben, beispielsweise die Supervisor-Konfiguration anstelle der crontab Einträge für den Scheduler zu ändern. Auf ein solches Beispiel wurde hier hingewiesen, bei dem eine Docker-Instanz verwendet wurde.
Beachten Sie schließlich, dass einige Laravel-Befehle andere Artisan-Befehle von innen aufrufen, offensichtlich ohne die Option --domain . Die obige Situation funktioniert nicht ordnungsgemäß, da der Unterbefehl mit der Standardumgebungsdatei funktioniert. Ein Beispiel ist der Befehl migrate bei Verwendung der Option --seed .