Laravel - 使用从中间件组返回的值作为全局变量

标签 laravel global-variables middleware

背景:我想对多个模板化网站使用相同的代码。我希望代码能够识别正在访问的域,然后能够设置要在整个应用程序中使用的全局变量。

首先,我创建了\config\global.php 并让其中的逻辑按预期工作:

$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);
    }
}

“$request->getHttpHost()”的结果是我需要的……它返回 www.foo.com 的“foo”。但是,我不知道如何将这个值分配给一个变量并通过“$next”返回它,然后我如何围绕它设置逻辑来设置我可以在 Blade 部分中引用的全局变量,等等。

谢谢!

编辑:如果使用\config\global.php 真的是完成我想要的事情的正确方法,我可以在我想执行“php artisan”命令时只注释掉“url()”行吗?

最佳答案

有几种不同的方法可以解决这个问题,最简单的方法是使用 config——它允许您动态获取和设置配置值。

  1. 创建一个名为 config/sites.php 的新文件,其中包含每个站点的数组,确保每个域都以 www 开头并替换任何 在带有 - 的域中(因为配置键中的 . 将不起作用,因为 Laravel 使用句点访问子值)。
return [
    'default' => [
        'id' => 15,
        'name' => 'Default Full Name',
        'abbreviation' => 'Def',
    ],
    'www-webdomain1-com' => [
        'id' => 25,
        'name' => 'Domain 1 Full Name',
        'abbreviation' => 'Web1',
    ],
    'www-webdomain2-com' => [
        'id' => 35,
        'name' => 'Domain 2 Full Name',
        'abbreviation' => 'Web2',
    ],
];

您现在可以在应用程序的任何位置访问每个站点的配置值,例如:config('sites.www-webdomain1-com.name')

  1. 将以下内容添加到您的中间件中:
public function handle($request, Closure $next)
{
    $host = str_slug(starts_with('www.', $request->getHttpHost()));

    $configuration = config("sites.{$host}") ?: config('sites.default');

    config(['site' => $configuration]);

    return $next($request);
}

您现在已将键 site 的配置值设置为您在 config/sites.php 中为请求域设置的站点配置的内容。

  1. 在任何需要访问事件站点配置选项的地方使用 config('site.property'),例如:
Hello, welcome to {{ config('site.name') }}

有更好的方法来解决这个问题,我个人会创建一个 Site 模型,然后使用 Route Model Binding然而,我在这里概述的方法对于初学者来说非常容易设置,应该可以满足您的需求。

关于Laravel - 使用从中间件组返回的值作为全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55153946/

相关文章:

arrays - 找出数字的所有数字是否相等

c++ - 类中的全局和外部

Laravel ServiceProvider vs. 中间件

php - 查询字符串问题中的自定义 Oauth 服务器和符号

php - .env 文件和 .ini 文件有什么区别?哪一个更好?

jquery - Ajax/Jquery & Laravel - 动态下拉选择并将选择值提取到文本框

node.js - Windows 7 NODE_PATH 全局变量设置但在 package.json 中无法识别

php - Laravel 在动态添加数据库名称后刷新数据库配置缓存

laravel - 将 'auth' 中间件与子域一起使用

reactjs - React App-createProxyMiddleware不是函数