Php Laravel路由区域设置中间件不使用模型绑定

Php Laravel路由区域设置中间件不使用模型绑定,php,laravel,Php,Laravel,我使用本指南: 我有以下路线和中间件: $locale = request()->segment(1); Route::middleware('localized')->prefix($locale)->group(function() { Route::get('/contacts', 'ContactController@index'); Route::get('/page/{page}', 'PageController@index'); });

我使用本指南:

我有以下路线和中间件:

$locale = request()->segment(1);

Route::middleware('localized')->prefix($locale)->group(function() {
     Route::get('/contacts', 'ContactController@index');
     Route::get('/page/{page}', 'PageController@index');
});
public function handle(Request $request, Closure $next)
{
    if (!array_key_exists($request->segment(1), config('translatable.locales'))) {
        $segments = $request->segments();

        $segments = Arr::prepend($segments, config('app.fallback_locale'));

        if($request->session()->has('language')) {
            $segments[0] = session('language');
        }

        return redirect()->to(implode('/', $segments));
    }
    
    return $next($request);
}
以及从Kernel.php->routemidware本地化的中间件:

$locale = request()->segment(1);

Route::middleware('localized')->prefix($locale)->group(function() {
     Route::get('/contacts', 'ContactController@index');
     Route::get('/page/{page}', 'PageController@index');
});
public function handle(Request $request, Closure $next)
{
    if (!array_key_exists($request->segment(1), config('translatable.locales'))) {
        $segments = $request->segments();

        $segments = Arr::prepend($segments, config('app.fallback_locale'));

        if($request->session()->has('language')) {
            $segments[0] = session('language');
        }

        return redirect()->to(implode('/', $segments));
    }
    
    return $next($request);
}
当我访问:site.test/contacts时,他会在locale:site.com/en/contacts上重定向我 当我访问site.test/page/test时,我没有找到404,如果我访问:site.com/en/page/test,那么页面工作。路由模型绑定的区域设置上的重定向问题

在控制器页面中,我有:

public function index(Page $page) 
{
    return view('page', compact('page'));
}
在translateable.php中:

'locales' => [
    'de' => 'Deutsch',
    'en' => 'English',
],
在AppServiceProvider中:

public function boot()
{
    if(array_key_exists(request()->segment(1), config('translatable.locales'))) {
        app()->setLocale(request()->segment(1));
    }
}

我能够解决这个问题,但这会使我们无法访问会话,您检查了会话以了解会话是否具有“语言”。如果是,则应将prepend locale值设置为会话中的语言值。下面是我所做的

路由文件中的

$locale = request()->segment(1);

Route::prefix($locale)->group(function() {
     Route::get('/contacts', function(){
         echo "hello contact";
     });
     Route::get('/page/{page}', function(Request $request, $page){
        return "hello Page {$page}";
     });
});
在中间件文件中我做了

public function handle(Request $request, Closure $next)
{
    if (!array_key_exists($request->segment(1), config('translatable.locales'))) {
    $segments = $request->segments();

    $segments = Arr::prepend($segments, config('app.fallback_locale'));
    
    // Remove the session check as we don't have access to session yet
    /*if($request->session()->has('language')) {
        $segments[0] = session('language');
    }*/

    return redirect()->to(implode('/', $segments));
}

    return $next($request);
}
public function handle(Request $request, Closure $next)
{
    if (!array_key_exists($request->segment(1), config('translatable.locales'))) {
    $segments = $request->segments();

    $segments = Arr::prepend($segments, config('app.fallback_locale'));
    
    // We can have session back on
    if($request->session()->has('language')) {
        $segments[0] = session('language');
    }

    return redirect()->to(implode('/', $segments));
}

    return $next($request);
}
现在,在中间件的Kennel.php文件中,将中间件类添加到$Middleware数组中

/**
 * The application's global HTTP middleware stack.
 *
 * These middleware are run during every request to your application.
 *
 * @var array
 */
protected $middleware = [
    ...
    \App\Http\Middleware\Localized::class, //This is the Localized Middlewere class
];
然后尝试访问site.test/page/1000。。。它将被重定向到site.test/{app.fallback_locale}/page/1000。在我的例子中,site.test/en/page/1000

更新

看完这篇文章后,我想在本地化中产阶级之前加入这个环节,结果奏效了。我不确定这是否是一个好的做法,但它完成了工作

在中间件文件中我做了

public function handle(Request $request, Closure $next)
{
    if (!array_key_exists($request->segment(1), config('translatable.locales'))) {
    $segments = $request->segments();

    $segments = Arr::prepend($segments, config('app.fallback_locale'));
    
    // Remove the session check as we don't have access to session yet
    /*if($request->session()->has('language')) {
        $segments[0] = session('language');
    }*/

    return redirect()->to(implode('/', $segments));
}

    return $next($request);
}
public function handle(Request $request, Closure $next)
{
    if (!array_key_exists($request->segment(1), config('translatable.locales'))) {
    $segments = $request->segments();

    $segments = Arr::prepend($segments, config('app.fallback_locale'));
    
    // We can have session back on
    if($request->session()->has('language')) {
        $segments[0] = session('language');
    }

    return redirect()->to(implode('/', $segments));
}

    return $next($request);
}
现在,在Kennel.php文件中的中间件中,在本地化中间件类之前添加会话中间件

/**
 * The application's global HTTP middleware stack.
 *
 * These middleware are run during every request to your application.
 *
 * @var array
 */
protected $middleware = [
    ...
    \Illuminate\Session\Middleware\StartSession::class,
    \App\Http\Middleware\Localized::class, //This is the Localized Middlewere class
];

我能够解决这个问题,但这会使我们无法访问会话,您检查了会话以了解会话是否具有“语言”。如果是,则应将prepend locale值设置为会话中的语言值。下面是我所做的

路由文件中的

$locale = request()->segment(1);

Route::prefix($locale)->group(function() {
     Route::get('/contacts', function(){
         echo "hello contact";
     });
     Route::get('/page/{page}', function(Request $request, $page){
        return "hello Page {$page}";
     });
});
在中间件文件中我做了

public function handle(Request $request, Closure $next)
{
    if (!array_key_exists($request->segment(1), config('translatable.locales'))) {
    $segments = $request->segments();

    $segments = Arr::prepend($segments, config('app.fallback_locale'));
    
    // Remove the session check as we don't have access to session yet
    /*if($request->session()->has('language')) {
        $segments[0] = session('language');
    }*/

    return redirect()->to(implode('/', $segments));
}

    return $next($request);
}
public function handle(Request $request, Closure $next)
{
    if (!array_key_exists($request->segment(1), config('translatable.locales'))) {
    $segments = $request->segments();

    $segments = Arr::prepend($segments, config('app.fallback_locale'));
    
    // We can have session back on
    if($request->session()->has('language')) {
        $segments[0] = session('language');
    }

    return redirect()->to(implode('/', $segments));
}

    return $next($request);
}
现在,在中间件的Kennel.php文件中,将中间件类添加到$Middleware数组中

/**
 * The application's global HTTP middleware stack.
 *
 * These middleware are run during every request to your application.
 *
 * @var array
 */
protected $middleware = [
    ...
    \App\Http\Middleware\Localized::class, //This is the Localized Middlewere class
];
然后尝试访问site.test/page/1000。。。它将被重定向到site.test/{app.fallback_locale}/page/1000。在我的例子中,site.test/en/page/1000

更新

看完这篇文章后,我想在本地化中产阶级之前加入这个环节,结果奏效了。我不确定这是否是一个好的做法,但它完成了工作

在中间件文件中我做了

public function handle(Request $request, Closure $next)
{
    if (!array_key_exists($request->segment(1), config('translatable.locales'))) {
    $segments = $request->segments();

    $segments = Arr::prepend($segments, config('app.fallback_locale'));
    
    // Remove the session check as we don't have access to session yet
    /*if($request->session()->has('language')) {
        $segments[0] = session('language');
    }*/

    return redirect()->to(implode('/', $segments));
}

    return $next($request);
}
public function handle(Request $request, Closure $next)
{
    if (!array_key_exists($request->segment(1), config('translatable.locales'))) {
    $segments = $request->segments();

    $segments = Arr::prepend($segments, config('app.fallback_locale'));
    
    // We can have session back on
    if($request->session()->has('language')) {
        $segments[0] = session('language');
    }

    return redirect()->to(implode('/', $segments));
}

    return $next($request);
}
现在,在Kennel.php文件中的中间件中,在本地化中间件类之前添加会话中间件

/**
 * The application's global HTTP middleware stack.
 *
 * These middleware are run during every request to your application.
 *
 * @var array
 */
protected $middleware = [
    ...
    \Illuminate\Session\Middleware\StartSession::class,
    \App\Http\Middleware\Localized::class, //This is the Localized Middlewere class
];

您确定上面的示例代码有效吗?当我试图复制“当我访问:site.test/contacts时,他会在locale:site.com/en/contacts上重定向我”,但除非我添加locale-site.test/fr/contacts,否则它对我无效。。然后它就起作用了。你的translateable.php配置文件设置如何?@kolawolemanuelizzy我用配置和提供者更新了我的问题。是的,我的代码有效你确定上面的示例代码有效吗?当我试图复制“当我访问:site.test/contacts时,他会在locale:site.com/en/contacts上重定向我”,但除非我添加locale-site.test/fr/contacts,否则它对我无效。。然后它就起作用了。你的translateable.php配置文件设置如何?@kolawolemanuelizzy我用配置和提供者更新了我的问题。是的,我的代码有效,但我需要保存会话:)),您的解决方案将影响所有路由,但我只需要影响我想要的路由。更新了我的回答是的,但路由问题仍然存在,我不需要影响所有路由。我有从拉拉维尔诺瓦来的路线,我的诺瓦不工作。当我访问:site.com/nova时,他在site.com/en/nova上重定向我。我找不到404。。。在/nova上我不需要Middleware您可以使用if-check排除这些路由(您已经可以在中间件中访问nova(即$segments[1]),但我需要保存会话:),您的解决方案将影响所有路由,但我只需要影响路由,这是我想要的。更新了我的回答,但路由问题仍然存在,我不需要影响所有路线。我有从拉拉维尔诺瓦来的路线,我的诺瓦不工作。当我访问:site.com/nova时,他在site.com/en/nova上重定向我。我找不到404。。。在/nova上,我不需要Middleware您可以使用if-check排除这些路由(您已经可以在中间件中访问nova(即$segments[1])