将新方法添加到Laravel中的资源控制器

use*_*824 126 laravel

我想知道是否可以向Laravel中的资源控制器添加新方法以及如何执行此操作.

我知道这些方法是默认的(索引,创建,存储,编辑,更新,销毁).现在我想添加其他方法和路由到同一个控制器.

那可能吗?

Jos*_*ber 239

注册资源之前,只需单独添加到该方法的路由:

Route::get('foo/bar', 'FooController@bar');
Route::resource('foo', 'FooController');
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您的新方法必须**以上*:: resource`,否则您会收到错误消息"没有模型的查询结果". (7认同)
  • @RicardoVigatti - 资源注册了这条路线:`Route :: get('foo/{id}',...)`.这会吞下所有以`foo`开头并有一个额外段的路线,包括`foo/bar`. (3认同)

Ant*_*iro 31

我只是这样做,添加一个GET"删除"方法.

创建文件后,您只需添加即可

'AntonioRibeiro\Routing\ExtendedRouterServiceProvider',
Run Code Online (Sandbox Code Playgroud)

到app/config.php中的'providers'

在同一个文件中编辑Route别名:

'Route'           => 'Illuminate\Support\Facades\Route',
Run Code Online (Sandbox Code Playgroud)

改变它

'Route'           => 'AntonioRibeiro\Facades\ExtendedRouteFacade',
Run Code Online (Sandbox Code Playgroud)

并确保这些文件是自动加载的,它们必须位于composer.json中的某个目录中("autoload"部分).

然后你只需要:

Route::resource('users', 'UsersController');
Run Code Online (Sandbox Code Playgroud)

如果你运行,这个(看最后一行)是结果php artisan routes:

路线清单 这些是我的源文件:

ExtendedRouteFacade.pas

<?php namespace AntonioRibeiro\Facades;

use Illuminate\Support\Facades\Facade as IlluminateFacade;

class ExtendedRouteFacade extends IlluminateFacade {

    /**
     * Determine if the current route matches a given name.
     *
     * @param  string  $name
     * @return bool
     */
    public static function is($name)
    {
        return static::$app['router']->currentRouteNamed($name);
    }

    /**
     * Determine if the current route uses a given controller action.
     *
     * @param  string  $action
     * @return bool
     */
    public static function uses($action)
    {
        return static::$app['router']->currentRouteUses($action);
    }

    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor() { return 'router'; }

}
Run Code Online (Sandbox Code Playgroud)

ExtendedRouter.pas

<?php namespace AntonioRibeiro\Routing;

class ExtendedRouter extends \Illuminate\Routing\Router {

    protected $resourceDefaults = array('index', 'create', 'store', 'show', 'edit', 'update', 'destroy', 'delete');

    /**
     * Add the show method for a resourceful route.
     *
     * @param  string  $name
     * @param  string  $base
     * @param  string  $controller
     * @return void
     */
    protected function addResourceDelete($name, $base, $controller)
    {
        $uri = $this->getResourceUri($name).'/{'.$base.'}/destroy';

        return $this->get($uri, $this->getResourceAction($name, $controller, 'delete'));
    }

}
Run Code Online (Sandbox Code Playgroud)

ExtendedRouteServiceProvider.pas

<?php namespace AntonioRibeiro\Routing;

use Illuminate\Support\ServiceProvider;

class ExtendedRouterServiceProvider extends ServiceProvider {

    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    protected $defer = true;

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->app['router'] = $this->app->share(function() { return new ExtendedRouter($this->app); });
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return array('router');
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 您能为Laravel 5及更高版本提供相同的功能吗?我一直在尝试重现这一点……但是我似乎找不到他们在容器中注册“ route”访问器的位置。 (2认同)
  • 为什么该文件的扩展名为 .pas? (2认同)

小智 16

是的,这可能......

在我的例子中,我添加方法:数据来处理HTTP POST方法中对/data.json的请求.

这就是我做的.

首先,我们扩展Illuminate\Routing\ResourceRegistrar以添加新的方法数据

<?php

namespace App\MyCustom\Routing;

use Illuminate\Routing\ResourceRegistrar as OriginalRegistrar;

class ResourceRegistrar extends OriginalRegistrar
{
    // add data to the array
    /**
     * The default actions for a resourceful controller.
     *
     * @var array
     */
    protected $resourceDefaults = ['index', 'create', 'store', 'show', 'edit', 'update', 'destroy', 'data'];


    /**
     * Add the data method for a resourceful route.
     *
     * @param  string  $name
     * @param  string  $base
     * @param  string  $controller
     * @param  array   $options
     * @return \Illuminate\Routing\Route
     */
    protected function addResourceData($name, $base, $controller, $options)
    {
        $uri = $this->getResourceUri($name).'/data.json';

        $action = $this->getResourceAction($name, $controller, 'data', $options);

        return $this->router->post($uri, $action);
    }
}
Run Code Online (Sandbox Code Playgroud)

之后,创建新的ServiceProvider或使用AppServiceProvider.

在方法引导中,添加以下代码:

    public function boot()
    {
        $registrar = new \App\MyCustom\Routing\ResourceRegistrar($this->app['router']);

        $this->app->bind('Illuminate\Routing\ResourceRegistrar', function () use ($registrar) {
            return $registrar;
        });
    }
Run Code Online (Sandbox Code Playgroud)

然后 :

添加到您的路线:

Route::resource('test', 'TestController');
Run Code Online (Sandbox Code Playgroud)

检查php artisan route:list 你会发现新的方法'数据'


小智 13

Route::resource('foo', 'FooController');
Route::controller('foo', 'FooController');
Run Code Online (Sandbox Code Playgroud)

试一试.请输入getData()等其他方法.这对我有用,可以保持route.php干净