在多域設定中使用 Laravel 的擴展
該套件允許單一 Laravel 安裝使用多個 HTTP 網域。
在很多情況下,不同的客戶在程式碼方面使用相同的應用程序,但在資料庫、儲存和配置方面卻不同。
這個套件提供了一種非常簡單的方法來獲取每個此類客戶的特定環境文件、特定儲存路徑和特定資料庫。
拉維爾 | 多域 |
---|---|
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 |
發布 v1.1.x:
到目前為止,版本 v1.1.6+、v1.2.x、v1.3.x、v1.4.x、v2.x 和 v3.x 在功能上是等效的。版本已分開,以便與相應版本的 Laravel 框架執行整合測試。
然而,隨著 Laravel 8 的發布,版本 v1.1.14、v1.2.8、v1.3.8 和 v1.4.8 是最新版本,包括相應 Laravel 5.x 版本的新功能(該版本的錯誤修復支援仍然有效) 。 2021-02-13 更新:v1.1+ 版本的一些最新功能仍在進行中:)
v1.0 需要 Laravel 5.1、5.2、5.3 和 5.4(與 Laravel 5.4 相比,不再維護和測試,但套件的用法與 1.1 相同)
2023-02-20 更新:從 Laravel 10.x 開始,套件版本遵循相同的編號。
新增 gecche/laravel-multidomain 作為 Composer.json 的要求:
{
"require" : {
"gecche/laravel-multidomain" : "11.*"
}
}
使用composer update 更新您的軟體包或使用composer install 進行安裝。
您也可以使用composer require gecche/laravel-multidomain
新增套件,然後指定您想要的版本。
該套件需要在引導過程一開始就覆蓋 Laravel 核心函數的最小集合中對 HTTP 域的偵測,以便取得特定的環境檔案。所以這個套件比大多數 Laravel 套件需要更多的設定步驟。
安裝步驟:
bootstrap/app.php
檔案最頂部的以下行來替換整個 Laravel 容器。 //use Illuminate F oundation A pplication
use Gecche Multidomain Foundation Application
config/app.php
檔案中的擴充版本覆寫QueueServiceProvider
,如下所示: ' 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 (),
請注意,如果您因其他原因更改了config/app.php
文件,則該文件中可能已經存在上述providers
條目,唯一重要的行是取代QueueServiceProvider
的行。
php artisan vendor:publish
(這個包利用了發現功能。)
按照上述步驟,您的應用程式將了解正在執行的 HTTP 網域,包括 HTTP 和 CLI 請求,包括佇列支援。
注意:在 Laravel 11 中,安裝比以前更簡單:如果您使用先前版本的 Laravel,請查看文件中的安裝步驟。
該軟體包與 Horizon 相容,這得益於社區的貢獻。如果您需要將此軟體包與 Horizon 一起使用,則必須遵循其他兩個安裝步驟:
像往常一樣安裝 Laravel Horizon
替換 app/Providers/HorizonServiceProvider.php 檔案最頂部的 Laravel Horizon 導入。
//use Laravel H orizon H orizonApplicationServiceProvider ;
use Gecche Multidomain Horizon HorizonApplicationServiceProvider ;
該軟體包添加了三個命令來管理您的應用程式 HTTP 網域:
domain.add
artisan 指令主要命令是domain:add
命令,它將要添加到應用程式的HTTP 域的名稱作為參數。假設我們有兩個網域site1.com
和site2.com
,共享相同的程式碼。
我們簡單地做:
php artisan domain:add site1.com
和
php artisan domain:add site2.com
這些命令會建立兩個新的環境檔案.env.site1.com
和.env.site2.com
,您可以在其中放置每個網站的特定配置(例如資料庫配置、快取配置和其他配置,通常在環境中找到)文件)。
該指令也會在config/domains.php
檔案的domains
鍵中加入一個項目。
此外,還會建立兩個新資料夾: storage/site1_com/
和storage/site2_com/
。它們具有與主存儲相同的資料夾結構。
對此storage
結構的自訂必須與config/domain.php
檔案中的值相符。
domain.remove
artisan 指令domain:remove
指令透過刪除應用程式的環境檔案來刪除指定的 HTTP 網域。例如:
php artisan domain:remove site2.com
新增force
選項將刪除網域儲存資料夾。
該指令也會從config/domains.php
檔案中的domains
鍵中刪除對應的條目。
domain.update_env
artisan 指令domain:update_env
指令傳遞一個 json 編碼的資料數組來更新一個或所有環境檔案。這些值將會加到對應 .env 的末尾。
透過新增domain
參數來更新單一網域環境檔案。
當domain
參數不存在時,該指令將更新所有環境文件,包括標準.env
文件。
要更新的網域清單保存在domain.php
設定檔中。
例如:
php artisan domain:update_env --domain_values='{"TOM_DRIVER":"TOMMY"}'
會將TOM_DRIVER=TOMMY
行加入到所有網域環境檔案中。
domain.list
artisan 指令domain:list
指令列出目前安裝的網域及其 .env 檔案和儲存路徑 dir。
此清單保存在config/domain.php
設定檔的domains
鍵中。
此清單會在每次執行domain:add
和domain:remove
命令時自動更新。
config:cache
artisan 命令config:cache artisan 命令可以與此套件一起使用,就像任何其他 artisan 命令一樣。
請注意,此命令將為執行該命令的每個網域產生一個 config.php 檔案。即命令
php artisan config:cache --domain=site2.com
將產生文件
config-site2_com.php
在運行時,目前的 HTTP 網域被維護在 laravel 容器中,並且可以透過該套件新增的domain()
方法來存取。
可以使用domainList()
方法。它傳回一個包含已安裝網域資訊的關聯數組,類似於上面的domain.list
命令。
例如
[
site1.com => [
'storage_path' => <LARAVEL-STORAGE-PATH>/site1_com,
'env' => '.env.site1.com'
]
]
對於應用程式收到的每個 HTTP 請求,都會載入特定的環境檔案並使用特定的儲存資料夾。
如果未找到特定環境文件和/或儲存資料夾,則使用標準環境文件和/或儲存資料夾。
正確 HTTP 網域的偵測是透過使用$_SERVER['SERVER_NAME']
PHP 變數來完成的。
重要提示:在某些執行環境中 $_SERVER['SERVER_NAME'] 未實例化,因此在您如下所述自訂 HTTP 網域的偵測之前,此套件無法正常運作。
從版本 1.1.15 開始,可以自訂 HTTP 網域的偵測,將Closure
傳遞為Application
建構函式的新domainParams
參數的domain_detection_function_web
條目。在下列範例中,HTTP 網域偵測依賴$_SERVER['HTTP_HOST']
而非$_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 ();
為了區分域,每個 artisan 指令都接受一個新選項: domain
。例如:
php artisan list --domain=site1.com
該命令將使用相應的網域設定。
artisan 指令queue:work
和queue:listen
指令已更新以接受新的domain
選項。
php artisan queue:work --domain=site1.com
與往常一樣,上述命令將使用相應的網域設定。
請記住,例如,如果您正在使用database
驅動程序,並且有兩個網域共享同一個資料庫,那麼如果您想單獨管理每個網域的作業,則應該使用兩個不同的佇列。
例如,您可以:
QUEUE_DEFAULT=default1
for site1.com 和QUEUE_DEFAULT=default2
for site2.comqueue.php
設定檔: 'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => env('QUEUE_DEFAULT','default'),
'retry_after' => 90,
],
php artisan queue:work --domain=site1.com --queue=default1
和
php artisan queue:work --domain=site1.com --queue=default2
顯然,除了sync
驅動程式之外,還可以對每個其他佇列驅動程式執行相同的操作。
storage:link
命令如果您使用storage:link
命令並且希望為每個網域建立一個不同的符號鏈接,則必須手動建立它們,因為到目前為止,此類命令總是會建立一個名為storage
鏈接,並且該名稱在命令中硬編碼。擴充storage:link
指令允許選擇名稱超出了這個套件的範圍(我希望它能在 Laravel 的未來版本中直接完成)。
獲取多個儲存連結的方法可能如下。讓我們假設有兩個網域,即site1.com
和site2.com
以及關聯的儲存資料夾storage/site1_com
和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
和.env.site2.com
中,我們新增一個條目,例如第一個網域: APP_PUBLIC_STORAGE=-site1_com
filesystems.php
設定檔中,我們更改如下: 'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage'.env('APP_PUBLIC_STORAGE'),
'visibility' => 'public',
],
此外,如果您在單頁應用程式 (SPA) 設定中使用該套件,您可以透過 .htaccess 或 Scaenicus 在其 .htaccess 解決方案中指出的類似解決方案更好地處理每個網域的不同公共資源。
從版本1.1.11 開始,第二個參數已新增至Application 建構函式中,以便選擇放置環境檔案的資料夾:如果您有數十個網域,則將環境檔案放在Laravel 應用程式的根目錄中並不是很愉快資料夾。
因此,如果您想使用不同的資料夾,只需將其新增至bootstrap/app.php
檔案的最頂部即可。例如,如果要將環境檔案新增至envs
子資料夾中,只需執行以下操作:
//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 ();
如果不指定第二個參數,則假定為標準資料夾。請注意,如果您指定資料夾,則標準.env
檔案也必須放置在其中
如果您嘗試在某個網域(例如sub1.site1.com
下執行網頁或 shell 命令,且該網域沒有特定的環境文件,即檔案.env.sub1.site1.com
不存在,則軟體套件將透過使用點分割網域來使用第一個可用的環境檔案。在此範例中,套件在以下文件中搜尋第一個環境文件:
.env.site1.com
.env.com
.env
同樣的邏輯也適用於儲存資料夾。
如果在您的設定中使用 Laravel 的調度程序,請記住命令schedule:run
也必須使用網域選項啟動。因此,您必須為每個網域啟動一個調度程序。一開始,人們可能會認為一個 Scheduler 實例應該處理為任何域啟動的命令,但 Scheduler 本身是在 Laravel 應用程式中運行的,因此它運行的“env”會自動應用於每個計劃的命令,並且--domain
選項根本沒有任何作用。
這也適用於像 Supervisor 這樣的外部工具:如果您使用 Supervisor 來執行 artisan 命令,例如queue:work
命令,請務必為您要處理的每個網域準備一個命令。
由於上述原因,在某些情況下該套件無法運作:在這些設定中,您無法變更例如主管配置而不是調度程序的crontab
條目。這裡已經指出了這樣一個使用 Docker 實例的範例。
最後,請注意,某些 Laravel 命令從內部呼叫其他 Artisan 命令,顯然沒有--domain
選項。上述情況無法正常運作,因為子命令將使用標準環境文件。一個範例是使用--seed
選項時的migrate
指令。