web-dev-qa-db-ja.com

Laravel-すべてのルートに(:any?)ワイルドカードを使用しますか?

ルーティングに少し問題があります。

私はCMSに取り組んでおり、2つの主要なルートが必要です。 _/admin_および/(:any)adminコントローラーはルート_/admin_に使用され、viewコントローラーは_/admin_以外に使用する必要があります。 viewコントローラーから、URLを解析して正しいコンテンツを表示します。

これは私が持っているものです:

_Route::get(array('admin', 'admin/dashboard'), array('as' => 'admin', 'uses' =>'admin.dashboard@index'));
Route::any('(:any)', 'view@index');
_

最初のルートは機能しますが、2番目のルートは機能しません。私はそれで少し遊んでみましたが、疑問符なしで_(:any)_を使用すると、_/_の後に何かを置いた場合にのみ機能するようです。 i doに疑問符を付けた場合、まったく機能しません。

次のすべてのルートをview @ indexに移動します。

_/
/something
/something/something
/something/something/something
/something/something/something/something
...etc...
_

これは、_(:any?)/(:any?)/(:any?)/(:any?)_の束をハードコーディングせずに可能ですか?

これについて最善の方法は何ですか?

49
qwerty

編集:Laravel 4このトピックに関するリリース以来、この答えはLaravel 3。

これにアプローチする方法はいくつかあります。

最初の方法は(:any)/(:all?)に一致しています:

Route::any('(:any)/(:all?)', function($first, $rest=''){
    $page = $rest ? "{$first}/{$rest}" : $first;
    dd($page);
});

複数のパラメーターに分割され、何らかの理由で(:all)が単独では機能しないため、最適なソリューションではありません(バグ?)

2番目の解決策は、正規表現を使用することです。これは、私の意見では上記よりも優れた方法です。

Route::any( '(.*)', function( $page ){
    dd($page);
});

ルートが404を返した場合、ルートが他のパターンと一致する場合でもcmsページがあるかどうかを確認できるメソッドがもう1つあります。このメソッドは、routes.phpで定義されたイベントリスナーを変更します。

Event::listen('404', function() {
    $page = URI::current();
    // custom logic, else
    return Response::error('404');
});

ただし、私が好む方法は#2です。これがお役に立てば幸いです。何をするにしても、これらのすべてのルートをキャッチする他のすべてのルートを必ず定義してください。その後に定義されたルートはトリガーされません。

26

ララヴェル5

このソリューションは、Laravel 5:

Route::get('/admin', function () {

  // url /admin

});

Route::get('/{any}', function ($any) {

  // any other url, subfolders also

})->where('any', '.*');

ルーメン5

これは代わりにルーメン用です:

$app->get('/admin', function () use ($app) {
  //
});

$app->get('/{any:.*}', function ($any) use ($app) {
  //
});
81
Andrea

404ステータスを押すのは少し間違っているようです。これにより、404を記録するときにあらゆる種類の問題が発生する可能性があります。私は最近Laravel 4で同じワイルドカードルーティングの問題にぶつかり、次のスニペットでそれを解決しました。

Route::any('{slug}', function($slug)
{
    //do whatever you want with the slug
})->where('slug', '([A-z\d-\/_.]+)?');

これにより、制御された方法で問題を解決できます。正規表現は次のように簡略化できます。

'(.*)?'

ただし、これは自己責任で使用する必要があります。

編集(追加):

これにより多くのルートが上書きされるため、「App :: before」ステートメントでラップすることを検討する必要があります。

    App::before(function($request) {
            //put your routes here
    });

この方法では、後で定義するカスタムルートは上書きされません。

46
Route::get("{path}", "SomeController@serve")->where('path', '.+');

上記のコードは、言及した再帰サブURLをキャプチャします。

/
/something
/something/something
/something/something/something
/something/something/something/something

Admin/*などの他の特別な場合は、この前にキャプチャできます。

7
Guy

ルートファイルの最後にこれを追加します

App::missing(function($exception)
{
    return View::make('notfound');
});

from http://scotch.io/tutorials/simple-and-easy-laravel-routing

5
Edmhs

誰かが何かをつなぎ合わせるのに役立つ場合に備えて、私の経験を綴ってください。

Laravelで自己APIを消費するReactアプリを作成しました。Laravel/ Lumenが提供する単一のビューがあります。Reactルーターを使用しています。- アプリ内のリンクをクリックすることは常に機能しましたが、URLの入力には次の考慮事項が必要でした:

In Laravel web.php routesファイルで次を使用しました:

Route::view('/{path?}', 'app')
    ->where('path', '.*')
    ->name('react');

そして、すべてがうまくいきました。

その後、プロジェクトをルーメンに切り替えました。この投稿のおかげで、web.phpのrouteファイルで次を使用しました。

$router->get('/{all:.*}', function() {
    return view('app');
});

これは、次のような第1レベルのURLで機能しました。

/
/something 

しかしながら、

/something/something etc.

しませんでした。

Google Developerツールのネットワークタブを見て、app.jsのURLがapp.jsの前に/ somethingを追加していて、次のような上位層URL

myapp.com/something
app.js URL:  myapp.com/js/app.js  (as it should be)

myapp.com/something/something
app.js URL:  myapp.com/something/js/app.js  (not found)

私がしなければならなかったのは、次のようなシングルビューページでapp.jsソースに先頭のスラッシュを追加することだけでした。

<script src="/js/app.js" defer></script>

の代わりに:

<script src="js/app.js" defer></script>

そう:

これはLaravelで機能しました(js/app.js URLを自動的に解決した可能性があるBladeファイルでした)

<script src="{{ asset('js/app.js') }}" defer></script>

Route::view('/{path?}', 'app')
    ->where('path', '.*')
    ->name('react');

しかし、私はLumen(Bladeファイルではない)でこれをしなければなりませんでした:

<script src="/js/app.js" defer></script>

$router->get('/{all:.*}', function() {
    return view('app');
});
2
Luke

ウィリアムのソリューションに感謝します。ただし、方法1と2はもう機能していませんLaravel 4。Laravel 4でソリューション#3を使用するには、start/global.phpファイルで404イベントを起動する必要があります。

App::error(function(Exception $exception, $code)
{
    // i.o. -> this is our catchall!
    // http://stackoverflow.com/questions/13297278/laravel-using-any-wildcard-for-all-routes
    Event::fire('404');

    return View::make('error')->with('exception', $exception)->with('code', $code);

    Log::error($exception);
});

これで、routes.phpファイルでこれを処理できます。

Event::listen('404', function() {
    // url?
    $url = Request::path();

    // LOGIC HERE

    // else
    return View::make('error');
});
2

基本的なルーメンの足場を持つ。私の場合、2つのフロントエンドアプリとAPIルートがあります

<?php // routes/web.php
/** @var \Laravel\Lumen\Routing\Router $router */

$router->group([
    'prefix' => '/api/v1',
    'namespace' => 'App\Http\Controllers'
], function () use ($router) {

    require 'routes-group1.php';
    require 'routes-group2.php';
    // ...
});

$router->get('/admin{any:.*}', function () {
    return file_get_contents('../public/a/index.html');
});

$router->get('{any:.*}', function () {
    return file_get_contents('../public/m/index.html');
});
1
Andrew Luca