امتداد لاستخدام 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+ مستمرة :)
يتطلب الإصدار 1.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
list النطاقات المثبتة حاليًا، مع ملف .env الخاص بها ومسار التخزين الخاص بها.
يتم الاحتفاظ بالقائمة في مفتاح domains
لملف التكوين config/domain.php
.
يتم تحديث هذه القائمة تلقائيًا عند تشغيل أوامر domain:add
والمجال domain:remove
.
config:cache
المؤقتيمكن استخدام الأمر الحرفي config:cache مع هذه الحزمة بنفس طريقة استخدام أي أمر حرفي آخر.
لاحظ أن هذا الأمر سيقوم بإنشاء ملف 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
الجديدة لمنشئ 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',
],
علاوة على ذلك، إذا كنت تستخدم الحزمة في إعداد تطبيق صفحة واحدة (SPA)، فيمكنك التعامل بشكل أفضل مع الموارد العامة المميزة لكل مجال عبر .htaccess أو حلول مماثلة كما أشار Scaenicus في حل .htaccess الخاص به.
بدءًا من الإصدار 1.1.11، تمت إضافة وسيطة ثانية إلى مُنشئ التطبيق من أجل اختيار المجلد الذي سيتم وضع ملفات البيئة فيه: إذا كان لديك عشرات النطاقات، فليس من الجيد أن يكون لديك ملفات بيئة في تطبيق 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
القياسي فيه
إذا حاولت تشغيل صفحة ويب أو أمر Shell ضمن مجال معين، على سبيل المثال، sub1.site1.com
ولا يوجد ملف بيئة محدد لذلك المجال، أي أن الملف .env.sub1.site1.com
غير موجود، ستستخدم الحزمة أول ملف بيئة متاح عن طريق تقسيم اسم المجال بالنقاط. في هذا المثال، تقوم الحزمة بالبحث عن ملف البيئة الأول بين ما يلي:
.env.site1.com
.env.com
.env
ينطبق نفس المنطق على مجلد التخزين أيضًا.
إذا كنت تستخدم برنامج جدولة Laravel في إعداداتك، فتذكر أنه يجب أيضًا تشغيل الأمر schedule:run
مع خيار النطاق. ومن ثم، عليك إطلاق برنامج جدولة لكل مجال. في البداية قد يعتقد المرء أن مثيل جدولة واحد يجب أن يتعامل مع الأوامر التي يتم إطلاقها لأي مجال، ولكن يتم تشغيل المجدول نفسه ضمن تطبيق Laravel، وبالتالي فإن "env" الذي يتم تشغيله من خلاله، ينطبق تلقائيًا على كل أمر مجدول --domain
خيار --domain
ليس له أي تأثير على الإطلاق.
وينطبق الشيء نفسه على الأدوات الخارجية مثل Supervisor: إذا كنت تستخدم Supervisor للأوامر الحرفية، على سبيل المثال، أمر queue:work
، فيرجى التأكد من إعداد أمر لكل مجال تريد التعامل معه.
بسبب ما سبق، هناك بعض الحالات التي لا يمكن أن تعمل فيها الحزمة: في تلك الإعدادات حيث لا يكون لديك إمكانية تغيير، على سبيل المثال، تكوين المشرف بدلاً من إدخالات crontab
الخاصة بالمجدول. تمت الإشارة إلى مثل هذا المثال هنا حيث تم استخدام مثيل Docker.
أخيرًا، انتبه إلى أن بعض أوامر Laravel تستدعي أوامر Artisan الأخرى من الداخل، ومن الواضح بدون خيار --domain
. الوضع أعلاه لا يعمل بشكل صحيح لأن الأمر الفرعي سيعمل مع ملف البيئة القياسي. ومن الأمثلة على ذلك أمر migrate
عند استخدام خيار --seed
.