Laravel - Utilisation (:?) joker pour tous les itinéraires?

j'ai un peu de mal avec le routage.

je travaille sur un CMS, et j'ai besoin de deux routes principales. /admin et /(:any) . Le contrôleur admin est utilisé pour la route /admin , et le contrôleur view devrait être utilisé pour toute autre chose que /admin . À partir du contrôleur view , je vais analyser l'url et afficher le contenu correct.

C'est ce que j'ai:

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

la première voie fonctionne, mais pas la seconde. J'ai joué avec un peu, et il semble que si j'utilise (:any) sans le point d'interrogation, ça ne marche que si je mets quelque chose après / . Si je do mettre le point d'interrogation, il ne fonctionne pas du tout.

je veux que toutes les routes suivantes aillent à view@index:

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

est-ce possible sans codage dur un tas de (:any?)/(:any?)/(:any?)/(:any?) (que je ne connais même pas fonctionne)?

Quelle est la meilleure façon de procéder?

43
demandé sur Laurence 2012-11-09 00:29:31

7 réponses

Edit: il y a eu une certaine confusion depuis la sortie de Laravel 4 sur ce sujet, cette réponse visait Laravel 3.

Il ya quelques façons d'aborder cette.

la première méthode est la correspondance (:any)/(:all?) :

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

N'est pas la meilleure solution car il se brise en plusieurs paramètres, et pour une raison quelconque (: tout) ne fonctionne pas tout seul (bug?)

la deuxième solution est pour utiliser une expression régulière, c'est une meilleure façon que ci-dessus, à mon avis.

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

il y a une autre méthode, qui vous permettrait de vérifier s'il y a des pages cms même si la route peut avoir correspondu à d'autres modèles, à condition que ces routes aient retourné un 404. Cette méthode modifie l'écouteur d'événements défini dans routes.php :

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

cependant, ma méthode préférée est #2. J'espère que cette aide. Quoi que vous fassiez, assurez-vous de définir tous vos autres routes au-dessus de ces captures toutes les routes, toutes les routes définies après ne se déclencheront jamais.

22
répondu William Cahill-Manley 2013-04-23 22:07:09

Laravel 5

Cette solution fonctionne très bien sur Laravel 5:

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

  // url /admin

});

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

  // any other url, subfolders also

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

Lumen 5

c'est pour Lumen à la place:

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

$app->get('/{any:.*}', function ($any) use ($app) {
  //
});
66
répondu Andrea 2017-02-03 10:47:19

atteindre un statut 404 me semble un peu erroné. Cela peut vous mettre dans toutes sortes de problèmes lors de la journalisation des 404. J'ai récemment rencontré le même problème de routage de jokers dans Laravel 4 et je l'ai résolu avec L'extrait suivant:

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

cela devrait résoudre votre problème d'une manière contrôlée. L'expression régulière peut être simplifiée à:

'(.*)?'

Mais vous devez utiliser à vos propres risques.

Modifier (ajout):

comme ceci écrase beaucoup de routes, vous devriez envisager de l'emballer dans un "App:: avant" déclaration:

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

de cette façon, il n'écrasera pas les routes personnalisées que vous définirez plus tard.

45
répondu Eelke van den Bos 2013-08-08 12:20:17
Route::get("{path}", "SomeController@serve")->where('path', '.+');

le code ci-dessus va capturer les urls de sub récursives que vous avez mentionnées:

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

tous les autres cas spéciaux, tels que admin/*, que vous pouvez capturer avant celui-ci.

5
répondu Guy 2016-01-02 18:54:34

ajouter ceci dans le fichier fin des routes

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

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

4
répondu Edmhs 2014-05-26 11:22:32

Merci pour la solution William. Cependant les méthodes 1 & 2 ne fonctionnent plus Laravel 4, et pour utiliser la solution #3 dans Laravel 4 vous devrez lancer l'événement 404 dans votre start/global.fichier php.

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

Maintenant, nous pouvons gérer cela dans nos itinéraires.fichier php:

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

    // LOGIC HERE

    // else
    return View::make('error');
});
2
répondu Chris Schalenborgh 2013-03-13 23:43:11

ayant un échafaudage de lumen de base. Dans mon cas, j'ai 2 applications frontend et les routes 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
répondu Andrew Luca 2018-01-17 03:41:39