Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Страницы 1
Всем привет, как в 5.8 получить в родительском контроллере текущий роут или контроллер? Гугл выдает много способов, но ни один не работает, то краш, то выдает не то что нужно.
Не в сети
А что тебе нужно и какой именно креш происходит в каком случае?
Route::currentRouteName()
Изменено artoodetoo (11.09.2020 13:41:40)
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
Route::currentRouteName()
это возвращает null
Route::getCurrentRoute() - это работает, но оно выдает общее правило которое сработало, а нужно текущее значение в этом правиле, вообще мне нужно идентифицировать вызванный action+controller
Не в сети
Значит у текущего маршрута нет имени
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
Возвращаемся к началу: что ты хочешь получить? Не надо писать "роут". Маршрут это объект, ты можешь его получить как request()->route(), например. Но ты наверное хочешь имя или путь. Что именно?
Что значит "родительский контроллер"? Мы к тебе в голову не можем залезть, будь добр(а) объяснить что это и почему посчитал(а) важным это упомянуть в вопросе.
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
Что значит "родительский контроллер"
есть FrontController, от него наследуются все контроллеры которые генерят фронтСтраницы, мне нужно на страницу в зависимости от имени контроллера и экшена подтягивать метатеги, для этого в FrontController до рендера должна вызватся функция которая на основании текущего контроллера и экшена вытянет из базы нужные метатеги, в yii это делается очень просто, а здесь не могу найти как получить имя контроллера и экшена, пытался через роуты это сделать, но по ходу не выйдет, должен же быть способ получания имени экшина и контроллера...
Не в сети
в апи есть метод получения контроллера https://laravel.com/api/5.8/Illuminate/ … Controller, но он не работает, там баг - ругается на mb_strpos, на гитхабе писали про это - https://github.com/laravel/framework/issues/20507, но как понял так и не пофиксили
Не в сети
Теперь это уже не "родительский", а "фронт-контроллер" )
В 100% случаев когда пишут про встроенную или библиотечную функцию что "она не работает", дело оказывается в том, что её неправильно используют.
Читаем про метод getController(): Get the controller instance for the route.
Инстанс! Он возвращает указатель на объект контроллера. Не имя, а объект. Если тебе нужно получить из него имя класса, то примени еще одну функцию: get_class()
Я не поленился и создал тестовый проект 5.8 с таким роутом и контроллером:
Route::get('/test', 'BaseController@routeInfo')->name('test');
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class BaseController extends Controller
{
public function routeInfo()
{
$route = request()->route();
return [
'getController' => get_class($route->getController()),
'getName' => $route->getName(),
'getActionName' => $route->getActionName(),
'getActionMethod' => $route->getActionMethod(),
];
}
}
Вот результат:
getController: "App\\Http\\Controllers\\BaseController"
getName: "test"
getActionName: "App\\Http\\Controllers\\BaseController@routeInfo"
getActionMethod: "routeInfo"
Можно унаследовать новый контроллер от BaseController и обращаться к $this->routeInfo(), будет корректная информация о текущем маршруте. Прочто читай доки внимательно, никакой сложности и "багов" здесь нет.
Изменено artoodetoo (12.09.2020 09:10:49)
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
Инстанс! Он возвращает указатель на объект контроллера
я вкурсе что такое инстанс , не первый год как программист
у меня код request()->route()->getController() выдает такое эрор "mb_strpos() expects parameter 1 to be string, object given"
а код request()->route()->getActionMethod() выдает - Closure
и я понял почему, при таком простом роуте
Route::get('/test', 'BaseController@routeInfo')->name('test');
все хорошо, но у меня фронтовые контроллеры работают по такому правилу
Route::any('/{slug1}/{slug2}', function($slug1,$slug2) {
return App::make('App\Http\Controllers\front\\'.ucfirst($slug1).'Controller')->$slug2();
});
Как в этом случае быть? нужно как-то узнать значения {slug1} и {slug2}, просто брать с урла - не вариант, ну точнее можно но это точно будет не элегантное решение, так как сделана для сеошников автозамена урлов на вбитые из админки.
Изменено Koten4ik (13.09.2020 20:14:51)
Не в сети
Не знаю чем тебе помочь. Ты сам провоцируешь ошибку. Что ты хотел получить в качестве имени, когда использовал замыкание?
Фактически, ты отказался от стандартной маршрутизации, что-то городишь своё.
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
Что ты хотел получить в качестве имени, когда использовал замыкание
Я хочу получить имя контроллера и акшена, система же знает какой котнроллер и акшен она запустила, просто это надо делать видимо не через роут, так как функции ларавела просто парсят строку из статического роута - параметр 'BaseController@routeInfo', но если роут в виде правила, то такое уже не работает. Я пытаюсь найти метод которые система выдает уже после обработки маршрута и вызова конкретного акшена, в этот момент она же знает уже все и может сообщить это.
Фактически, ты отказался от стандартной маршрутизации, что-то городишь своё.
не свое, а подибие правила которое в yii идет из коробки, я много проработал на yii и скажу что такие правила очень удобны! Избавляют от простыней в роутере.
Изменено Koten4ik (14.09.2020 11:44:46)
Не в сети
- система же знает какой котнроллер и акшен
Нет. Она знает, что текущему маргруту сопоставлено замыкание. Если ты думал, что объект Маршрут бежит по стеку вызовов и проверяет не является ли нечто контроллером: знай, это не так )
- не свое, а подибие правила которое в yii идет из коробки
То есть городишь своё. Ты повелитель сего. Отвелл снимает с себя ответственность.
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
Если ты думал, что объект Маршрут бежит по стеку
Я ничего не думал, я искал метод получания имени контроллера при правеле маршрута который я указал. Не нашел, решил спросить у опытных в Ларавел, но ответа пока не получил.
То есть городишь своё
Ну почему свое? Если это не коректное правило роута, то как тогда подобное сделать корректно? А оно бывает нужно и очень удобно, не верю что в средних и выше проектах, где экшинов за сотню переваливает пишут на каждый - статический маршрут, создавая при этом простыню, в которой потом черт ногу сломит!
В yii это идет из коробки, и при этом система фреймворка всегда может тебе сообщить имя контроллера и экшена.
Не в сети
Ты конечно можешь делать как тебе нравится, речь о том, что с т.з. Ларавель твой контроллер это замыкание. Ты отошел от стандартного поведения и теперь ты сам творец своего счастья. Сделай функцию с параметрами контроллер и экшн, пусть она сохраняет их куда-то и потом инстанциирует контроллер.
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
Когда-нибудь ты захочешь использовать именованные маршруты или рут миддлвары и обнаружишь, что Ларавель опять не хочет тебе помогать, по той же причине: маршрут у тебя всего один в терминах Ларавель.
Такой маршрут-на-все-случаи не может быть кеширован средствами Ларавель.
Отказываясь от стандартов ты берёшь на себя ответственность за последствия.
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
Когда-нибудь ты захочешь использовать именованные маршруты или рут миддлвары и обнаружишь
Да, понадобилось использовать событие - beforeAction, и как выяснилось это тоже не работает из-за этого моего роута с анонимной функцией, зачем таковые тогда нужны если при них ничего не работает, и главный вопрос - как сделать такое: указываешь Ларавелу в урл /controllerName/actionName и он исходя из такого урла вызывает соответсвующий экшен контроллера? Или это невозможно в Ларавел без потери его фунциональности? Если да то оочень странно, так как это очень удобно и в yii это прям из коробки идет.
Не в сети
урл /controllerName/actionName и он исходя из такого урла вызывает соответсвующий экшен контроллера?
Не уж то никто такого не делал?
Не в сети
Не уж то никто такого не делал?
Я работаю в проекте где подобное есть, но от такого подхода уже отказались. Оно существует как легаси, мы вынуждены эту версию поддерживать пока она не будет полностью вытеснена новой.
Почему было когда-то сделано: якобы для оптимизации. На самом деле нет, это не оптимизация, т.к. кешированные маршруты работают быстро, а "динамический роутинг" в принципе не кешируется. Другая причина была в якобы простоте поиска экшенов. По мере роста оказалось что минусы перевешивают один хилый плюс.
Причина нелюбви: неудобство в организации роут мидлваре. Чем больше эндпоинтов, тем важнее становятся мидлвары доступа. Когда у тебя перед глазами классический ларавелевский файл маршрутов с группами, то вся логика доступа перед глазами. Да, *ля, он большой, очень большой. Но он читабельный, понятный. А "динамический роутинг" заставляет тебя помещать контроль доступа в контроллер и чтобы проверить его надо в каждый контроллер залезть.
Много дублирующего кода. Изменение в политике доступа приводит к необходимости переписывать массу файлов.
Итого: овчинка выделки не стоит. Экономия букв это хреновая оптимизация.
Изменено artoodetoo (22.09.2020 07:42:13)
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
Итого: овчинка выделки не стоит
Спасибо за развернутый ответ! Я бы на счет овчинк поспорил, но нет вермени на это. Такая штука очень удобна на этапе разработки во многих случаях, да - если много ветвлений по доступам - возможно и не очень, но такое далеко не во всех проектах, в общем ладно.
Я работаю в проекте где подобное есть
А как это реалезовано не используя замыкание? Если не секрет.
Не в сети
А как это реалезовано не используя замыкание? Если не секрет.
Во-первых, я не говорил, что замыкания там нет (хотя его там правда нет). Во-вторых, без разницы замыкание там или ссылка на экшен. Важно что с т.з. ларавель у тебя только один маршрут, который берёт на себя все запросы, что не были подобраны до него. Уже внутри этого дефолтового экшена происходят какие-то вычисления на базе URL и управление передаётся в другие контроллеры. То есть самописная маршрутизация поверх стандартной. Ларавелевский пайплайн с мидлварами уже не участвует в нём. Понимаешь о чём я? Видимо нет, т.к. ты мыслишь категориями Yii.
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
Не в сети
Понимаешь о чём я? Видимо нет
Умничание не делает человеку чести...
Ларавелевский пайплайн с мидлварами уже не участвует в нём
Тоесть все же нельзя на Ларавеле сделать эту удобную штуку без потери функциональности. Пайплайн не очень удачный значит в Ларавел, признайте это!:)
Не в сети
Не знаю чем тебе помочь. Ты сам провоцируешь ошибку
Забудь за мой код, мне нужно чтобы урл site.ru/aaa/bbb вызывал акшн bbb у контроллера aaa, чтобы это работало без явного вписывания маршрута aaa/bbb в файл маршрутов, чтобы был какойто маршрут-формула которая бы обрабатывала такие урлы. Такое сделать возможно в ларавел без потери функциональности?
Не в сети
В 100% случаев когда пишут про встроенную или библиотечную функцию что "она не работает", дело оказывается в том, что её неправильно используют.
Не в сети
я это уже слышал, но никто не предложил работающего варианта
Не в сети
Страницы 1