Подтвердить что ты не робот

Laravel - Использование (: any?) Шаблона для ВСЕХ маршрутов?

У меня проблемы с маршрутизацией.

Я работаю над CMS, и мне нужны два основных маршрута. /admin и /(:any). Контроллер admin используется для маршрута /admin, а контроллер view должен использоваться для чего-либо еще, кроме /admin. Из контроллера view я затем проанализирую URL и покажу правильный контент.

Это то, что у меня есть:

Route::get(array('admin', 'admin/dashboard'), array('as' => 'admin', 'uses' =>'[email protected]'));
Route::any('(:any)', '[email protected]');

Первый маршрут работает, а второй - нет. Я немного поиграл с ним, и кажется, что я использую (:any) без вопросительного знака, он работает только, если я положил что-то после /. Если я поставлю вопросительный знак там, он вообще не работает.

Я хочу, чтобы все следующие маршруты отображались в @index:

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

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

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

4b9b3361

Ответ 1

Изменить: с момента выпуска Laravel 4 по этой теме произошла некоторая путаница, этот ответ был нацелен на Laravel 3.

Есть несколько способов приблизиться к этому.

Первый метод - это сопоставление (:any)/(:all?):

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

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

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

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. Надеюсь, это поможет. Независимо от того, что вы делаете, убедитесь, что вы определили все свои другие маршруты выше этих поймать все маршруты, любые маршруты, определенные после этого, никогда не будут срабатывать.

Ответ 2

Laravel 5

Это решение отлично работает на Laravel 5:

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

  // url /admin

});

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

  // any other url, subfolders also

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

Lumen 5

Это вместо Lumen:

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

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

Ответ 3

Нажатие статуса 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
    });

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

Ответ 4

Route::get("{path}", "[email protected]")->where('path', '.+');

В приведенном выше коде будут учтены рекурсивные юниты, которые вы упомянули:

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

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

Ответ 6

Спасибо за решение William. Однако методы 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);
});

Теперь мы можем справиться с этим в нашем файле routes.php:

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

    // LOGIC HERE

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

Ответ 7

Наличие базовых лесов просвета. В моем случае у меня есть 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');
});

Ответ 8

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

Я построил самообслуживаемое приложение 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

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

с

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

Но я должен был сделать это в Люмене:

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

с

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