【问题标题】:Laravel app()->getLocale() inside routes always print the default "en"路由内部的 Laravel app()->getLocale() 总是打印默认的“en”
【发布时间】:2019-01-27 00:36:21
【问题描述】:

我在尝试使用新设置的区域设置为我的路线添加前缀时遇到了一个问题。 当我从控制器或路由闭包返回 app()->getLocale() 时,它会正确返回新的设置语言环境,但是当我将它放在路由前缀中时,我会得到默认的“en”。在我的例子中,新的语言环境是 'ar'。

这是我在 web.php 中的代码

<?php


//Request to put the choosen locale into the session
Route::get('locale/{locale}', function($locale) {

    session()->put('userLocale', $locale);
    return redirect(app()->getLocale());
});

//Group of routes that are supposed to be prefixed with new set locale 'ar'
Route::group(['prefix' => app()->getLocale(), 'middleware' => 'locale'], function() {

    Route::get('/', function() {
        return app()->getLocale();
    });
});

这是中间件:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Foundation\Application;
use Illuminate\Http\Request;

class Locale
{
    protected $app;

    public function __construct(Application $app)
    {
        $this->app = $app;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $this->app->setLocale(session('userLocale'));
        return $next($request);
    }
}

注意 Route 前缀中的语句“app()->getLocale()”,该语句的值始终为“en”。但是当我从闭包中返回它时,它会打印新设置的语言环境“ar”。

我想说的是,在前缀内部,app()->getLocale() 的值始终为“en”,但在闭包内部其值为“ar”。

所以当我在浏览器中运行“localehost:8000/locale/ar”时,输出是“ar”,这是正确的,但 url 变成了“localehost:8000/en”,应该是“localehost:8000/ar” “不是吗?当我在浏览器中运行“localehost:8000/ar”时,我得到一个 404 页面。

我尝试在 RouteServiceProvider 的 mapWebRoutes 方法中设置前缀,但它不起作用,因为我认为服务提供者是在中间件之前执行的,所以它无法识别新的语言环境由中间件设置。

我希望获得帮助或另一种方法来为路线添加新的语言环境前缀,因为也许我做错了什么。

【问题讨论】:

    标签: php laravel localization


    【解决方案1】:

    在您的中间件运行之前,不会从会话中设置您的语言环境。您的路由必须在中间件运行之前定义,否则系统将不知道应该在哪些路由上运行哪个中间件。

    由于 app()->locale() 将在中间件运行之前返回 'en',因此您的代码所做的就是定义一个前缀 'en'。

    您似乎想为语言环境定义一个变量,在这种情况下,您可以执行以下操作:

    Route::group(['prefix' => '{locale}', 'middleware' => 'locale'], function() {
       ...
    });
    

    或者您可以使用为您处理本地化网址的包,例如 https://github.com/mcamara/laravel-localization

    【讨论】:

    • 谢谢。我试试看
    • 如何才能在中间件运行之前定义路由?
    【解决方案2】:

    制作一个名为 SetLocale 的中间件,如下所示,并将其注册到 kernel.php 文件中:

    public function handle($request, Closure $next)
    {
        $desiredLocale=$request->segment(1);
        in_array($desiredLocale, ["en", "ar"]) ? app()->setLocale($desiredLocale) : app()->setLocale('en');
    
        return $next($request);
    }
    

    在 kernel.php 中添加 $routeMiddleware 数组,如下所示:

    'local.set'=>\App\Http\Middleware\SetLocale::class,
    

    现在,您可以像这样将其应用于所有路线:

    Route::group(['prefix' => '{locale}','middleware' => 'local.set'], function () {
    ......
    });
    

    【讨论】:

      猜你喜欢
      • 2016-10-30
      • 2017-03-22
      • 1970-01-01
      • 1970-01-01
      • 2021-02-25
      • 2020-04-21
      • 2019-01-20
      • 2020-02-28
      • 2021-11-08
      相关资源
      最近更新 更多