向 Laravel 的资源控制器添加新方法

我想知道是否有可能在 Laravel 的资源控制器中添加新的方法,以及你是如何做到的。

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

这可能吗?

116698 次浏览

只需单独向该方法添加一个路由,之前就可以注册资源:

Route::get('foo/bar', 'FooController@bar');
Route::resource('foo', 'FooController');

我刚刚这样做了,添加了一个 GET“ delete”方法。

创建文件后,只需添加

'AntonioRibeiro\Routing\ExtendedRouterServiceProvider',

到你的 app/config.php 中的“提供者”

编辑同一文件中的 Route 别名:

'Route'           => 'Illuminate\Support\Facades\Route',

把它改成

'Route'           => 'AntonioRibeiro\Facades\ExtendedRouteFacade',

并确保这些文件正在自动加载,它们必须位于您的 comper.json (“ autoload”部分)中的某个目录中。

那你只需要:

Route::resource('users', 'UsersController');

这(看最后一行)是运行 php artisan routes的结果:

routes list 这些是我的源文件:

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'; }


}

扩展路由器

<?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 的清洁

这个也很不错。不需要添加更多的路由,只需使用资源控制器的 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(){}

我使用默认值来抛出自定义错误页面。

是的,有可能。

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

我就是这么做的。

首先,我们扩展 路由资源注册以添加新的方法 资料

<?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);
}
}

之后,使您的新 服务供应商或使用 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检查 你会发现新的方法 < strong > ‘ data’

只需添加一个新方法和该方法的路由。

在你的控制器中:

public function foo($bar=“default”)
{
//do stuff
}

还有你的网络路线

Route::get(“foo/{$bar}”, “MyController@foo”);

只需确保控制器中的方法是公共的。

使用 Laravel > 5 在路由文件夹中查找 web.php 文件添加您的方法

您可以使用 path: : resource 在一行中路由控制器中的所有这些方法索引、显示、存储、更新和销毁

Route::get('foo/bar', 'NameController@bar');
Route::resource('foo', 'NameController');

以前我把我的路线定义为:

Route::get('foo/bar', 'FooController@bar');
Route::resource('foo', 'FooController');

它指出了一个错误:

没有定义 path foo.bar

在谷歌了一下之后,我加了一个名字

Route::get('foo/bar', 'FooController@bar')->name('foo.bar');

而且效果很好。

我靠

创建扩展 BaseRouter的自定义路由器文件

// src/app/Custom/Router.php




<?php


namespace App\Custom;


use Illuminate\Routing\Router as BaseRouter;
use Illuminate\Support\Str;


class Router extends BaseRouter
{
public function customResource($name, $controller, array $options = [])
{
$model = Str::singular($name); // this is optional, i need it for Route Model Binding


$this
->get( // set the http methods
$name .'/{' . $model . '}/audit',
$controller . '@audit'
)->name($name . '.audit');


return $this->resource($name, $controller, $options);
}
}


然后在 src/bootstrap/app.php注册

$app->singleton('router', function ($app) {
return new \App\Custom\Router($app['events'], $app);
});

并在/path/web.php 上使用它

Route::customResource(
'entries',
'EntryController'
);

到 Laravel 9为止,这似乎已经变得简单多了。即使在创建 Resource 控制器之后添加新方法,以下方法也可以正常工作。

Route::get('/foo/bar', [FooController::class, 'bar']);


Route::resource('/foo', FooController::class);

只要确保在顶部包含新方法,因为剩下的/foo/[ any ]名称空间将保留给该行上的 Resource 控制器。这是 Laravel 路线的惯例。