Laravel-使用中间件组返回的全局变量值
背景:我想对多个模板化网站使用相同的代码。我希望代码能够识别正在访问的域,然后能够设置在整个应用程序中使用的全局变量 首先,我创建了\config\global.php,并使其中的逻辑按预期工作:Laravel-使用中间件组返回的全局变量值,laravel,global-variables,middleware,Laravel,Global Variables,Middleware,背景:我想对多个模板化网站使用相同的代码。我希望代码能够识别正在访问的域,然后能够设置在整个应用程序中使用的全局变量 首先,我创建了\config\global.php,并使其中的逻辑按预期工作: $webUrl = url()->current(); /************************************************** * Set Conference name based on URL ******************************
$webUrl = url()->current();
/**************************************************
* Set Conference name based on URL
**************************************************/
$confId = 0;
$confName = '';
$confAbbrev = '';
if(strpos($webUrl, 'webdomain1') > 0) {
$confName = 'Domain 1 Full Name';
$confAbbrev = 'Dom1';
$confId = 25;
}
elseif(strpos($webUrl, 'webdomain2') >0) {
$confName = 'Domain 2 Full Name';
$confAbbrev = 'Dom2';
$confId = 35;
}
然而,我最终发现“url()”导致了错误,使我无法在整个应用程序中使用“php artisan”命令。在咨询了我的专业web开发人员同事后,他说对全局变量使用“全局”配置文件不是最佳实践,建议使用中间件。他控制了我的笔记本电脑,速度非常快
在\app\Http\Kernel.php中,他在$middlewareGroups末尾添加了SetDomainVariables行:
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\SetDomainVariables::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
然后,他创建了一个新文件:\app\Http\Middleware\SetDomainVariables.php
<?php
namespace App\Http\Middleware;
use Closure;
class SetDomainVariables
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
dd($request->getHttpHost());
return $next($request);
}
}
解决此问题有几种不同的方法,最简单的方法是使用config
——它允许您动态获取和设置配置值
创建一个名为config/sites.php
的新文件,其中包含每个站点的数组,确保用www
启动每个域,并用-
替换域中的任何
(因为配置键中的
将无法工作,因为Laravel使用句点访问子值)
返回[
“默认值”=>[
“id”=>15,
“名称”=>“默认全名”,
'缩写'=>'定义',
],
“www-webdomain1-com”=>[
“id”=>25,
“名称”=>“域1全名”,
“缩写”=>“Web1”,
],
“www-webdomain2-com”=>[
“id”=>35,
'name'=>'Domain 2 Full name',
“缩写”=>“Web2”,
],
];
现在,您可以在应用程序的任何位置访问每个站点的配置值,例如:config('sites.www-webdomain1-com.name')
将以下内容添加到中间件:
公共函数句柄($request,Closure$next)
{
$host=str_slug(以('www.,$request->getHttpHost())开头);
$configuration=config(“sites.{$host}”)?:config(“sites.default”);
配置(['site'=>$configuration]);
返回$next($request);
}
现在,您已经将键site
的配置值设置为在请求域的config/sites.php
中设置的站点配置的内容
在需要访问活动站点的配置选项的任何位置使用config('site.property')
,例如:
您好,欢迎来到{{config('site.name')}
有更好的方法来解决这个问题,我个人会创建一个站点
模型,然后使用,但是我在这里概述的方法对于初学者来说非常容易设置,应该可以满足您的需要。谢谢。如果我走这条路,我能连接到config/sites.php中的数据库吗?我上面给出的示例(每个客户机网站的硬编码ID、名称和缩写)更多的是为了确保我有数据进行测试。但是我的数据库中有一个表,我可以在其中传递域名,并动态返回正确会议的ID、名称、缩写。现在我有两个客户机,但是如果我有10多个客户机,我觉得一个DB调用(传入域名)会更具可伸缩性。如果你使用的是数据库驱动,那么这是正确的方法,非常简单。创建子域路由组(“路由文档中的子域路由”)并为域路由中使用的密钥创建显式路由模型绑定,例如:route::Domain({conference}.example.com
)`然后route::bind('conference',…)
——所有这些都包含在文档中。如果你需要更多的指导,请告诉我。为了将来的参考,当你问这样的问题时,最好先概述一下你想要达到的目标,例如:“我的数据库中有会议,我希望每个会议都有一个可通过唯一子域访问的页面,该子域由模型上的domain
属性确定,例如:conference.example.com
是conferenceid
1“而不是概述你的解决方案是什么/你认为什么是解决方案。这为人们提供了帮助你实现目标所必需的信息:)我感谢你的意见。我将在未来几天内尝试实施您建议的更改。有一点需要澄清。。。这些将是单独的域,而不是同一网站的子域。我的第一个客户网站是www.pac7sports.org。。。我的第二个客户将是一个单独的会议。但由于内容的性质(体育成绩等),它们将共享同一个数据库,但是完全独立的域,我计划在其中部署相同的精确代码以减少维护。您不需要多次部署相同的代码库,您可以在同一Laravel安装中指向多个域,然后使用该域(无论是子域还是完整域)来确定加载了哪些数据。