将新方法添加到Laravel中的资源控制器
我想知道是否有可能向Laravel中的资源控制器添加新方法,以及如何执行此操作。
我知道这些方法是默认的(索引,创build,存储,编辑,更新,销毁)。 现在我想添加额外的方法和路线到同一个控制器。
那可能吗?
在注册资源之前,请单独向该方法添加路由:
Route::get('foo/bar', 'FooController@bar'); Route::resource('foo', 'FooController');
我只是这样做,添加一个GET“删除”的方法。
创build你的文件后,你只需要添加
'AntonioRibeiro\Routing\ExtendedRouterServiceProvider',
到'提供者'在你的app / config.php
在同一个文件中编辑路由别名:
'Route' => 'Illuminate\Support\Facades\Route',
改变它
'Route' => 'AntonioRibeiro\Facades\ExtendedRouteFacade',
并确保这些文件被自动加载,它们必须位于composer.json(“autoload”部分)中的某个目录中。
那么你只需要:
Route::resource('users', 'UsersController');
而这(看最后一行)是运行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'; } }
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')); } }
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'); } }
Route::resource('foo', 'FooController'); Route::controller('foo', 'FooController');
给你一个尝试。让你额外的方法,如getData()等等等。这对我来说保持route.php干净
是的,这是可能的..
在我的情况下,我添加方法:数据来处理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); } }
之后,制作新的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; }); }
然后 :
添加到您的路线:
Route::resource('test', 'TestController');
检查由php artisan route:list
你会发现新的方法'数据'
这工作也很好。 不需要添加更多的路由,只需要像这样使用资源控制器的show方法:
public function show($name){ switch ($name){ case 'foo': $this -> foo(); break; case 'bar': $this ->bar(); break; defautlt: abort(404,'bad request'); break; } } public function foo(){} publcc function bar(){}
我使用默认的自定义错误页面。