ส่วนขยายสำหรับการใช้ Laravel ในการตั้งค่าหลายโดเมน
แพ็คเกจนี้อนุญาตให้การติดตั้ง Laravel เดียวทำงานกับโดเมน HTTP หลายโดเมน
มีหลายกรณีที่ลูกค้าที่แตกต่างกันใช้แอปพลิเคชันเดียวกันในแง่ของโค้ด แต่ไม่ได้ใช้ในแง่ของฐานข้อมูล พื้นที่จัดเก็บ และการกำหนดค่า
แพ็คเกจนี้ให้วิธีที่ง่ายมากในการรับไฟล์ env เฉพาะ พาธพื้นที่เก็บข้อมูลเฉพาะ และฐานข้อมูลเฉพาะสำหรับลูกค้าแต่ละราย
ลาราเวล | มัลติโดเมน |
---|---|
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 ที่เกี่ยวข้อง (การสนับสนุนการแก้ไขข้อบกพร่องยังคงใช้งานได้สำหรับเวอร์ชันนั้น) . 13-02-2021 อัปเดต : คุณสมบัติล่าสุดบางอย่างสำหรับรุ่น 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 require gecche/laravel-multidomain
และระบุเวอร์ชันที่คุณต้องการในภายหลัง
แพ็คเกจนี้จำเป็นต้องแทนที่การตรวจจับโดเมน HTTP ในชุดฟังก์ชันหลัก Laravel ขั้นต่ำที่จุดเริ่มต้นของกระบวนการบูตสแตรปเพื่อรับไฟล์สภาพแวดล้อมเฉพาะ ดังนั้นแพ็คเกจนี้จำเป็นต้องมีขั้นตอนการกำหนดค่ามากกว่าแพ็คเกจ Laravel ส่วนใหญ่เล็กน้อย
ขั้นตอนการติดตั้ง:
bootstrap/app.php
//use Illuminate F oundation A pplication
use Gecche Multidomain Foundation Application
QueueServiceProvider
ด้วยส่วนขยายในไฟล์ config/app.php
ดังนี้: ' 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 ตามปกติ
แทนที่การนำเข้า Laravel Horizon ที่ด้านบนสุดของไฟล์ app/Providers/HorizonServiceProvider.php
//use Laravel H orizon H orizonApplicationServiceProvider ;
use Gecche Multidomain Horizon HorizonApplicationServiceProvider ;
แพ็คเกจนี้เพิ่มสามคำสั่งเพื่อจัดการโดเมน HTTP ของแอปพลิเคชันของคุณ:
domain.add
คำสั่งช่างฝีมือ คำสั่งหลักคือคำสั่ง 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
ซึ่งคุณสามารถกำหนดการกำหนดค่าเฉพาะสำหรับแต่ละไซต์ได้ (เช่น การกำหนดค่าฐานข้อมูล การกำหนดค่าแคช และการกำหนดค่าอื่นๆ ตามที่มักพบในสภาพแวดล้อม ไฟล์).
คำสั่งยังเพิ่มรายการในคีย์ domains
ในไฟล์ config/domains.php
นอกจากนี้ ยังมีการสร้างโฟลเดอร์ใหม่สองโฟลเดอร์ ได้แก่ storage/site1_com/
และ storage/site2_com/
มีโครงสร้างโฟลเดอร์เดียวกันกับที่จัดเก็บข้อมูลหลัก
การปรับแต่งโครงสร้างย่อยของ storage
นี้ต้องตรงกับค่าในไฟล์ config/domain.php
domain.remove
คำสั่งช่างฝีมือ คำสั่ง domain:remove
จะลบโดเมน HTTP ที่ระบุออกจากแอปพลิเคชันโดยการลบไฟล์สภาพแวดล้อม เช่น:
php artisan domain:remove site2.com
การเพิ่มตัวเลือก force
จะลบโฟลเดอร์ที่เก็บข้อมูลโดเมน
คำสั่งยังลบรายการที่เหมาะสมออกจากคีย์ domains
ในไฟล์ config/domains.php
domain.update_env
คำสั่ง 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
คำสั่ง domain:list
แสดงรายการโดเมนที่ติดตั้งในปัจจุบัน พร้อมด้วยไฟล์ .env และ dir เส้นทางการจัดเก็บข้อมูล
รายการจะคงอยู่ในคีย์ domains
ของไฟล์กำหนดค่า config/domain.php
รายการนี้ได้รับการอัปเดตโดยอัตโนมัติในทุก domain:add
และ domain:remove
คำสั่งที่ทำงาน
config:cache
คำสั่ง 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 ที่ถูกต้องทำได้โดยใช้ตัวแปร PHP $_SERVER['SERVER_NAME']
หมายเหตุสำคัญ: ในสภาพแวดล้อมการดำเนินการบางอย่าง $_SERVER['SERVER_NAME'] จะไม่ถูกสร้างอินสแตนซ์ ดังนั้นแพ็คเกจนี้จึงทำงานไม่ถูกต้องจนกว่าคุณจะปรับแต่งการตรวจหาโดเมน HTTP ตามที่อธิบายไว้ด้านล่าง
เริ่มตั้งแต่รุ่น 1.1.15 การตรวจหาโดเมน HTTP สามารถปรับแต่งได้โดยผ่าน Closure
เป็นรายการ domain_detection_function_web
ของอาร์กิวเมนต์ domainParams
ใหม่ของ Constructor ของ Application
ในตัวอย่างต่อไปนี้ การตรวจหาโดเมน 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 ();
เพื่อแยกความแตกต่างระหว่างโดเมน แต่ละคำสั่งของช่างฝีมือจะยอมรับตัวเลือกใหม่: domain
เช่น:
php artisan list --domain=site1.com
คำสั่งจะใช้การตั้งค่าโดเมนที่เกี่ยวข้อง
คำสั่ง queue:work
และ queue:listen
ของช่างฝีมือได้รับการอัปเดตเพื่อยอมรับตัวเลือก domain
ใหม่
php artisan queue:work --domain=site1.com
ตามปกติคำสั่งดังกล่าวจะใช้การตั้งค่าโดเมนที่เกี่ยวข้อง
โปรดทราบว่า ตัวอย่างเช่น หากคุณใช้ไดรเวอร์ database
และมีสองโดเมนที่ใช้ฐานข้อมูลเดียวกัน คุณควรใช้คิวที่แตกต่างกันสองคิวหากคุณต้องการจัดการงานของแต่ละโดเมนแยกกัน
ตัวอย่างเช่น คุณสามารถ:
QUEUE_DEFAULT=default1
สำหรับ site1.com และ QUEUE_DEFAULT=default2
สำหรับ 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',
],
นอกจากนี้ หากคุณใช้แพ็คเกจในการตั้งค่า Single Page Application (SPA) คุณจะจัดการทรัพยากรสาธารณะที่แตกต่างกันสำหรับแต่ละโดเมนได้ดีขึ้นผ่าน .htaccess หรือโซลูชันที่คล้ายกัน ตามที่ Scaenicus ชี้ให้เห็นในโซลูชัน .htaccess ของเขา
เริ่มต้นจากเวอร์ชัน 1.1.11 อาร์กิวเมนต์ที่สองได้ถูกเพิ่มเข้าไปใน Application Constructor เพื่อเลือกโฟลเดอร์ที่จะวางไฟล์สภาพแวดล้อม: หากคุณมีโดเมนหลายสิบโดเมน การมีไฟล์สภาพแวดล้อมในแอปของ 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
และไม่มีไฟล์สภาพแวดล้อมเฉพาะสำหรับโดเมนนั้น กล่าวคือ ไม่มีไฟล์ .env.sub1.site1.com
อยู่ package จะใช้ไฟล์สภาพแวดล้อมไฟล์แรกที่มีอยู่โดยแยกชื่อโดเมนด้วยจุด ในตัวอย่างนี้ แพ็กเกจค้นหาไฟล์สภาพแวดล้อมแรกจากรายการต่อไปนี้:
.env.site1.com
.env.com
.env
ตรรกะเดียวกันนี้ใช้กับโฟลเดอร์จัดเก็บข้อมูลเช่นกัน
หากในการตั้งค่าของคุณคุณใช้ Scheduler ของ Laravel โปรดจำไว้ว่าต้องเปิดใช้คำสั่ง schedule:run
ด้วยตัวเลือกโดเมนด้วย ดังนั้น คุณจะต้องเปิดตัวกำหนดเวลาสำหรับแต่ละโดเมน ในตอนแรกใคร ๆ ก็คิดว่าอินสแตนซ์ Scheduler หนึ่งตัวควรจัดการคำสั่งที่เรียกใช้สำหรับโดเมนใด ๆ แต่ตัวกำหนดตารางเวลาเองนั้นทำงานภายในแอปพลิเคชัน Laravel ดังนั้น "env" ที่รันอยู่นั้นจะถูกนำไปใช้กับแต่ละคำสั่งที่กำหนดเวลาไว้โดยอัตโนมัติและ --domain
ตัวเลือก --domain
ไม่มีผลใดๆ เลย
เช่นเดียวกับเครื่องมือภายนอก เช่น หัวหน้างาน: หากคุณใช้หัวหน้างานสำหรับคำสั่งของช่างฝีมือ เช่น คำสั่ง queue:work
โปรดแน่ใจว่าได้เตรียมคำสั่งสำหรับแต่ละโดเมนที่คุณต้องการจัดการ
จากที่กล่าวมาข้างต้น มีบางกรณีที่แพ็คเกจไม่สามารถทำงานได้: ในการตั้งค่าเหล่านั้นซึ่งคุณไม่สามารถเปลี่ยนแปลงได้ เช่น การกำหนดค่าของผู้บังคับบัญชา แทนที่จะเป็นรายการ crontab
สำหรับผู้กำหนดตารางเวลา ตัวอย่างดังกล่าวได้รับการชี้ให้เห็นที่นี่ซึ่งมีการใช้อินสแตนซ์ Docker
สุดท้ายนี้ โปรดทราบว่าคำสั่ง Laravel บางคำสั่งเรียกคำสั่ง Artisan อื่นๆ จากภายใน โดยเห็นได้ชัดว่าไม่มีตัวเลือก --domain
สถานการณ์ข้างต้นทำงานไม่ถูกต้อง เนื่องจากคำสั่งย่อยจะทำงานกับไฟล์สภาพแวดล้อมมาตรฐาน ตัวอย่างคือคำสั่ง migrate
เมื่อใช้ตัวเลือก --seed