Может войдёшь?
Черновики Написать статью Профиль

Возвращаем Route::controller() в Laravel 5.3 и выше

laravel php controllers routing

Как вы знаете, 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($slug1);
    }

    return 
$slug;
  }


  protected static function 
stringStartsWith($string$match)
  {
    return (
substr($string0strlen($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;
  }

}

Как этим пользоваться?

  1. Кидаем в папку app/classes файл с названием FRoute.php, вставляем в него код, который выше.
  2. Добавляем псевдоним в config/app.php
PHP
    'aliases' => [
        
//
    
'FRoute' => App\Classes\FRoute::class,
    ],
  1. Все, можно регистрировать контроллеры.
PHP
<?php
// /routes/web.php
FRoute::controller('/''PublicController');
FRoute::controller('admin''AdminController');
FRoute::controller('admin/users''Admin\UserController');
FRoute::controller('auth''AuthController');

Данный класс никак не влияет на контроллеры, DI в них, команды Artisan и тд, все будет работать как обычно.

Как вы считаете, полезен ли этот материал? Да Нет

Написать комментарий

Разметка: ? ?

Авторизуйся, чтобы прокомментировать.