В моем приложении появляется слишком много однотипных маршрутов. Разницы между ними практически нет, кроме названия контроллера и самого метода.
Например products/view_characteristics
, products/view_attributes
, products/view_info
, products/view_photos
и так далее.
Все они обрабатываются одним контроллером ProductsController
.
Как мне сделать что-то на подобии такого маршрута
Route::post('{controller}/{action}', function(){
// здесь вызываем переданный метод у переданного контроллера
});
Есть ли в самом фреймворке такая возможность(как вариант сторонние библиотеки) или придется пилить собственные велосипеды и костыли?
появляется слишком много однотипных маршрутов
Вы столкнётесь с проблемой, при выполнении кэширования маршрутов php artisan route:cache
:
Unable to prepare route ... for serialization. Uses Closure.
Маршруты с анонимными функциями не кэшируются.
Предположу, что метод должен быть всё таки get
:
// Ресурсный маршрут должен идти перед маршрутом из вопроса.
// Чтобы не было пересечений с маршрутом `products/{id}/edit`.
Route::resource('products', 'ProductsController');
// Маршрут из вопроса.
Route::get('products/{id}/{action}', 'ProductsController@detail');
Примерная обработка метода detail
в контроллере ProductsController
:
public function detail(int $id, string $action)
{
// Делаете выборку товара по $id.
...
// Возвращаете один из методов контроллера.
// Предварительно проверив его существование.
return $this->{camel_case($action)}();
}
Свою проблему я решил следующим методом.
Написал функцию которая будет обрабатывать логику и вызывать нужный метод у переданного контроллера. Также в параметрах функции есть возможность указать пространство имен(если контроллер находится подкаталоге) а также для вызываемого метода префикс(это суто под себя сделал).
if (!function_exists('simple_routing')) {
function simple_routing($controller, $action, $namespace_part, $action_prefix = '')
{
$namespace = '\\App\\Http\\Controllers\\' . $namespace_part . '\\' . \Illuminate\Support\Str::camel($controller) . 'Controller';
$object = new $namespace;
if (!method_exists($object, $action_prefix . $action)) {
abort(404, __('common.errors.post_404'));
}
return app()->call([new $namespace, $action_prefix . $action]);
}
}
Маршрут я прописывал следующим образом
Route::post('blog/{controller}/{action}', function ($controller, $action) {
return simple_routing($controller, $action, 'Blog', 'action_');
});
По своей сути пространство имен являет собой разбиение приложения на модули. Но это так к слову.
Спасибо @Walfter за то что подтолкнул в правильном направлении.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Можно ли сделать свой файл обработчик ajax, например testphp, который будет лежать в папке с темой, рядом с footer
В распоряжении имею php и js Нужно делать обращения к различным api Можно ли как то это совершать чтобы не было видно где происходит это обращение,...
Требуется реализовать возможность ввода данных в таблицы из админ-панели
Есть код, его суть - периодическое создание ордеров на продажу и покупку