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

时间:2013-05-21 02:36:32

标签: laravel

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

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

这可能吗?

9 个答案:

答案 0 :(得分:222)

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

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

答案 1 :(得分:30)

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

创建文件后,您只需添加

即可
'AntonioRibeiro\Routing\ExtendedRouterServiceProvider',

到app / config.php中的'providers'

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

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

将其更改为

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

确保这些文件是自动加载的,它们必须位于composer.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'; }

}

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

}

答案 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);
    }
}

之后,请创建新的 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检查 您会发现新方法&#39;数据

答案 3 :(得分:13)

Route::resource('foo', 'FooController');
Route::controller('foo', 'FooController');

尝试一下。给你额外的方法,比如getData()等等。这对我有用,可以保持route.php干净

答案 4 :(得分:1)

使用Laravel&gt; 5 在routes文件夹中找到web.php文件添加你的方法

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

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

答案 5 :(得分:1)

我解决

创建一个扩展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);
});

并在/routes/web.php

上使用它
Route::customResource(
    'entries',
    'EntryController'
);

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

以前,我将路线定义为:

DateTimeOffset past = yourTime.Subtract(TimeSpan.FromHours(3));

它给出了错误:

route foo.bar未定义

然后在谷歌搜索后我添加了姓名

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

效果很好。

答案 8 :(得分:-1)

只需为该方法添加新方法和路线。

在您的控制器中:

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

并在您的网络路线

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

确保控制器中的方法是公开的。