Вопрос:

Laravel - Using (:any?) wildcard for ALL routes?

php laravel routing wildcard laravel-3

70853 просмотра

8 ответа

2523 Репутация автора

I am having a bit of trouble with the routing.

I'm working on a CMS, and i need two primary routes. /admin and /(:any). The admin controller is used for the route /admin, and the view controller should be used for anything else than /admin. From the view controller, i will then parse the url and show the correct content.

This is what i have:

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

The first route works, but the second one doesn't. I played around with it a little bit, and it seems if i use (:any) without the question mark, it only works if i put something after /. If i do put the question mark there, it doesn't work at all.

I want all of the following routes to go to view@index:

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

Возможно ли это без жесткого кодирования кучу (:any?)/(:any?)/(:any?)/(:any?)(что я даже не знаю, работает)?

Какой лучший способ пойти по этому поводу?

Автор: qwerty Источник Размещён: 08.11.2012 08:29

Ответы (8)


25 плюса

2250 Репутация автора

Решение

Изменить: С момента выхода Laravel 4 по этой теме возникла путаница, этот ответ был нацелен на Laravel 3.

Есть несколько способов подойти к этому.

Первый метод соответствует (:any)/(:all?):

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

Не лучшее решение, потому что оно разбито на несколько параметров и по какой-то причине (: all) не работает само по себе (ошибка?)

Второе решение заключается в использовании регулярного выражения, по моему мнению, это лучший способ, чем описанный выше.

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

Есть еще один метод, который позволит вам проверить, существуют ли страницы CMS, даже если маршрут мог соответствовать другим шаблонам, при условии, что эти маршруты возвращали 404. Этот метод изменяет прослушиватель событий, определенный в routes.php:

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

Тем не менее, мой предпочтительный метод # 2. Надеюсь, это поможет. Что бы вы ни делали, убедитесь, что вы определили все остальные ваши маршруты выше этих перехватов, все маршруты, определенные после, никогда не сработают.

Автор: William Cahill-Manley Размещён: 08.11.2012 08:49

2 плюса

21 Репутация автора

Спасибо за решение, Уильям. Однако методы 1 и 2 больше не работают в Laravel 4, и чтобы использовать решение № 3 в Laravel 4, вам придется запустить событие 404 в файле start / global.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);
});

Теперь мы можем обработать это в нашем файле rout.php:

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

    // LOGIC HERE

    // else
    return View::make('error');
});
Автор: Chris Schalenborgh Размещён: 13.03.2013 11:43

46 плюса

1050 Репутация автора

Попадание в статус 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
    });

Таким образом, он не будет перезаписывать пользовательские маршруты, которые вы определите позже.

Автор: Eelke van den Bos Размещён: 23.03.2013 11:29

5 плюса

2551 Репутация автора

Добавьте это в конец файла маршрутов

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

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

Автор: Edmhs Размещён: 26.05.2014 11:22

78 плюса

7832 Репутация автора

Ларавел 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) {
  //
});
Автор: Andrea Размещён: 02.01.2016 10:50

7 плюса

625 Репутация автора

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

Приведенный выше код будет захватывать упомянутые вами рекурсивные субрлы:

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

Любые другие особые случаи, такие как admin / *, вы можете зафиксировать до этого.

Автор: Guy Размещён: 02.01.2016 06:54

1 плюс

1374 Репутация автора

Наличие базовых лесов просвета. В моем случае у меня есть 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');
});
Автор: Andrew Luca Размещён: 17.01.2018 03:29

0 плюса

11 Репутация автора

Просто изложите мой опыт на случай, если он поможет кому-то собрать что-то вместе.

Я построил самообслуживаемое приложение React на Laravel. Он имеет единый вид, обслуживаемый Laravel / Lumen. Он использует маршрутизатор React. Нажатие на ссылки в приложении всегда работало, но ввод URL-адресов требовал следующего рассмотрения:

В Laravel я использовал следующее в моем файле маршрутов web.php:

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

И все заработало.

Затем я переключил проект на Lumen. Благодаря этому сообщению я использовал следующее в моем файле маршрутов web.php:

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

Это работало для URL первого уровня, таких как:

/
/something 

Тем не мение,

/something/something etc.

не.

Я посмотрел на вкладке сети в инструментах разработчика Google и заметил, что URL для app.js добавлялся / что-то перед app.js на 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 (это был файл Blade, который мог автоматически разрешать URL-адрес js / app.js)

<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');
});
Автор: Luke Размещён: 27.04.2019 12:58
Вопросы из категории :
32x32