Как вы знаете, PHPRoute::controller()
был удален из Laravel 5.3 и выше.
Лично мне листать файл роута на 3 страницы, выискивая что на что ссылается не доставляет никакого удовольствия. Да, есть PHPRoute::resource()
, но хочется как в старое доброе время, прописал и забыл.
Короче, ниже класс для возвращения этого функционала.
PHP
<?php
namespace App\Classes;
class FRoute {
private static $methodNameAtStartOfStringPattern = null;
private static $httpMethods = [
'get',
'post',
'any',
'put',
'patch',
'delete',
];
public static function controller($path, $controllerClassName)
{
$class = new \ReflectionClass(app()->getNamespace().'Http\Controllers\\'.$controllerClassName);
$routes = [];
$publicMethods = $class->getMethods(\ReflectionMethod::IS_PUBLIC);
$methods = [];
foreach ($publicMethods as $method)
{
if ($method->name == 'getMiddleware')
{
continue;
}
$method->slug = self::slug($method);
$methods[] = $method;
}
usort($methods, function ($a, $b)
{
$aHasParam = false !== strpos($a->slug, '{');
$bHasParam = false !== strpos($b->slug, '{');
if (!$aHasParam && $bHasParam)
{
return -1;
}
if (!$bHasParam && $aHasParam)
{
return 1;
}
return (strcmp($a->slug, $b->slug));
});
foreach ($methods as $method)
{
$slug = $method->slug;
$methodName = $method->name;
$httpMethod = null;
foreach (self::$httpMethods as $httpMethod)
{
if (self::stringStartsWith($methodName, $httpMethod))
{
\Route::$httpMethod($path.'/'.$slug, $controllerClassName.'@'.$methodName);
$route = new \stdClass();
$route->httpMethod = $httpMethod;
$route->prefix = sprintf("Route::%-4s('%s',", $httpMethod, $path.'/'.$slug);
$route->target = $controllerClassName.'@'.$methodName;
$routes[] = $route;
break;
}
}
}
}
protected static function slug($method)
{
if (!self::$methodNameAtStartOfStringPattern)
{
self::$methodNameAtStartOfStringPattern = '/^('.implode('|', self::$httpMethods).')/';
}
$cleaned = preg_replace(self::$methodNameAtStartOfStringPattern, '', $method->name);
$snaked = \Illuminate\Support\Str::snake($cleaned, ' ');
$slug = str_slug($snaked, '-');
if ($slug == "index")
{
$slug = "";
}
foreach ($method->getParameters() as $parameter)
{
if (self::hasType($parameter))
{
continue;
}
$slug .= sprintf('/{%s%s}', strtolower($parameter->getName()), $parameter->isDefaultValueAvailable() ? '?' : '');
}
if ($slug != null && $slug[0] == '/')
{
return substr($slug, 1);
}
return $slug;
}
protected static function stringStartsWith($string, $match)
{
return (substr($string, 0, strlen($match)) == $match) ? true : false;
}
protected static function hasType(\ReflectionParameter $param)
{
preg_match('/\[\s\<\w+?>\s([\w]+)/s', $param->__toString(), $matches);
return isset($matches[1]) ? true : false;
}
}
- Кидаем в папку app/classes файл с названием FRoute.php, вставляем в него код, который выше.
- Добавляем псевдоним в config/app.php
PHP
'aliases' => [
//
'FRoute' => App\Classes\FRoute::class,
],
- Все, можно регистрировать контроллеры.
PHP
<?php
// /routes/web.php
FRoute::controller('/', 'PublicController');
FRoute::controller('admin', 'AdminController');
FRoute::controller('admin/users', 'Admin\UserController');
FRoute::controller('auth', 'AuthController');
Данный класс никак не влияет на контроллеры, DI в них, команды Artisan и тд, все будет работать как обычно.
Комментарии (1)
Ништяк все работает
P/s жаль не работают параметры
FRoute::controller('/pages','PagesController',['getCreate' => 'pages.create']);