首页 文章

扩展Laravel Router API

提问于
浏览
4

我正在尝试扩展Laravel 5.6路由器类,以添加一些方便的方法来注册路由 .

我创建了一个扩展 Illuminate\Routing\Router 类的类,如下所示:

Namespace App\Overrides;

use Illuminate\Routing\Router as LaravelRouter;

class Router extends LaravelRouter
{

    public function apiReadResource($name, $controller, array $options = [])
    {
        $this->resource($name, $controller, array_merge([
            'only' => ['index', 'show'],
        ], $options));
    }

    public function apiWriteResource($name, $controller, array $options = [])
    {
        $this->resource($name, $controller, array_merge([
            'except' => ['index', 'show', 'edit', 'create', 'destroy'],
        ], $options));
    }

    public function apiRelationshipResources($name, $controller, array $relationships, array $options = [])
    {
        foreach($relationships as $relationship)
        {
            $this->get(
                $name.'/{id}/'.$relationship,
                [
                    'uses' => $controller . '@' . $relationship,
                    'as'   => $name . '.' . $relationship,
                ]
            );
        }
    }

}

我在默认 App\Providers\RouteServiceProvider 中注册了我的扩展类:

namespace App\Providers;

use Illuminate\Routing\Router;
use App\Overrides\Router as APIRouter;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Route;

class RouteServiceProvider extends ServiceProvider
{
    /**
     * This namespace is applied to your controller routes.
     *
     * In addition, it is set as the URL generator's root namespace.
     *
     * @var string
     */
    protected $namespace = 'App\Http\Controllers';


    public function register()
    {
        $this->app->singleton('router', function ($app) {
            return new APIRouter($app['events'], $app);
        });
    }

    /**
     * Define your route model bindings, pattern filters, etc.
     *
     * @return void
     */
    public function boot()
    [more code...]
}

在路由文件中,我调用我自己的自定义方法,如下所示: Route::apiWriteResource('users', 'UserController'); 或像这样 Route::apiRelationshipResources('users', 'UserController', ['reviews']);

所有路线都已注册并在 php artisan route:list 中正确显示,但没有一条路线确实有效 . 它们都提供标准的404页面 .

我究竟做错了什么?我错过了什么?

1 回答

  • 1

    根据hereherehere的文档和Router.php检查,我开始想写一个答案 .

    请尝试以下步骤:

    1)在 app 文件夹中创建 Routing 文件夹

    创建 macros

    2) app\Routing\ApiReadResource.php 有这样的内容:

    <?php
    namespace App\Routing
    
    use Illuminate\Routing\Router;
    
    
    class ApiReadResource
    {
        public static function register()
        {
            if (!Router::hasMacro('apiReadResource')) {
                Router::macro('apiReadResource', function ($name, $controller, $options = []) {
                    Router::resource(
                       $name, 
                       $controller, 
                       array_merge(['only' => ['index', 'show']], $options)
                    );
                });
            }
        }
    }
    

    3) app\Routing\ApiWriteResource.php 有这样的内容:

    <?php
    namespace App\Routing
    
    use Illuminate\Routing\Router;
    
    
    class ApiWriteResource
    {
        public static function register()
        {
            if (!Router::hasMacro('apiWriteResource')) {
                Router::macro('apiWriteResource', function ($name, $controller, $options = []) {
                    Router::resource(
                       $name, 
                       $controller, 
                       array_merge(['except' => ['index', 'show', 'edit', 'create', 'destroy']], $options)
                    );
                });
            }
        }
    }
    

    4) app\Routing\ApiRelationshipResources.php 有这样的内容:

    <?php
    namespace App\Routing
    
    use Illuminate\Routing\Router;
    
    
    class ApiRelationshipResources
    {
        public static function register()
        {
            if (!Router::hasMacro('apiRelationshipResources')) {
                Router::macro('apiRelationshipResources', function ($name, $controller, array $relationships, $options = []) {
                  foreach($relationships AS $relationship) {
                    Router::get(
                       $name.'/{id}/'.$relationship,
                       array_merge($options, [
                         'uses' => $controller . '@' . $relationship,
                         'as'   => $name . '.' . $relationship,
                       ])
                    );
                  }
                });
            }
        }
    }
    

    5)在 AppServiceProvider 内注册它们:

    <?php
    namespace App\Providers;
    use Illuminate\Support\ServiceProvider;
    
    class AppServiceProvider extends ServiceProvider
    {
        /**
         * Bootstrap any application services.
         *
         * @return void
         */
        public function boot()
        {
    
        }
        /**
         * Register any application services.
         *
         * @return void
         */
        public function register()
        {
            \App\Routing\ApiReadResource::register();
            \App\Routing\ApiWriteResource::register();
            \App\Routing\ApiRelationshipResources::register();
        }
    }
    

相关问题