Laravel'de bir kaynak denetleyicisine yeni yöntemler ekleme


141

Laravel'de bir kaynak denetleyicisine yeni yöntemler eklemenin mümkün olup olmadığını ve bunu nasıl yaptığınızı bilmek istiyorum.

Bu yöntemlerin varsayılan olduğunu biliyorum (dizin, oluşturma, depolama, düzenleme, güncelleme, yok). Şimdi aynı denetleyiciye ek yöntemler ve yollar eklemek istiyorum.

Mümkün mü?

Yanıtlar:


261

Kaynağı kaydetmeden önce bu yönteme ayrı bir rota eklemeniz yeterlidir:

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

7
Yeni yöntemlerinizin yukarısına gitmesi gerektiğini unutmayın , ::resourceaksi takdirde "Model için sorgu sonucu yok" hata iletisini alırsınız.
mpen

{İd} gibi bir parametreyi nasıl iletirsiniz? Şu anda özel yöntemimi inline kodlamıyorum (buradaki örnek gibi laravel.com/docs/5.1/routing#route-parameters ). İdeal olarak FooController içinde çalıştırmak için parametre geçmek istiyorum.
ATutorMe

1
Sorunu buldum - Rota sözdiziminde değildi. Aslında kullandığım bazı özel Middleware oldu! Route :: get ('foo / {id} / bar', 'FooController @ bar'); kimliği bar ($ id) yöntemine geçirir. Teşekkürler!
ATutorMe

Birisi özel yolun neden kaynak yolunun üstüne çıkması gerektiğini açıklayabilir mi ??? Bazı testler yaptım ve yukarı veya aşağı koymak arasında hiçbir fark yok gibi görünüyor ...
Ricardo Vigatti

3
@RicardoVigatti - kaynak bu yolu kaydeder: Route::get('foo/{id}', ...). Bu foo, dahil olmak üzere bir ek segmente sahip olan tüm rotaları yutar foo/bar.
Joseph Silber

32

Ben sadece bir GET "delete" yöntemi eklemek için yaptım.

Dosyalarınızı oluşturduktan sonra,

'AntonioRibeiro\Routing\ExtendedRouterServiceProvider',

/ config.php dosyasındaki 'sağlayıcılara'

Aynı dosyadaki Rota diğer adını düzenleyin:

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

olarak değiştirmek

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

Ve bu dosyaların otomatik olarak yüklendiğinden emin olun, composer.json ("autoload" bölümünde) içinde bulunan bir dizinde bulunmaları gerekir.

O zaman yapmanız gerekenler:

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

Ve bu (son satıra bakın) eğer koşarsanız sonuçtur php artisan routes:

güzergah listesi Bunlar benim kaynak dosyam:

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

}

3
Laravel 5 ve Üstü için de aynısını verebilir misiniz? Ben bunu yeniden üretmeye çalışıyorum ... Ama kapsayıcıya 'rota' Erişiciyi nereye kaydettiklerini bulamıyorum.
TipuZaynSultan

dosya uzantısı neden .pas?
Thiago Dias

22

Evet, mümkün ..

Benim durumumda HTTP POST yönteminde /data.json isteğini işlemek için yöntem: veri ekliyorum.

Ben de öyle yaptım.

Önce Illuminate \ Routing \ ResourceRegistrar'ı yeni yöntem verileri eklemek üzere genişletiyoruz

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

Bundan sonra, yeni ServiceProvider'ınızı yapın veya bunun yerine AppServiceProvider'ı kullanın.

Yöntem önyüklemesine şu kodu ekleyin:

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

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

sonra :

rotanıza ekleyin:

Route::resource('test', 'TestController');

Tarafından kontrol edin php artisan route:list Ve yeni bir yöntem 'veri' bulacaksınız


Çözümünüz benim için çalışıyor .. Bu kodu kullanarak birkaç ay sonra herhangi bir sorun tespit edip etmediğinizi söyleyebilir misiniz?
Ricardo Vigatti

Teşekkürler @RicardoVigatti. Bunu laravel 5.2'den beri kullandım ve şimdi L5.3 ile son projemde kullanıyorum ve bununla ilgili bir sorunum yok. Eğer varsa, bana bildirin, ben size yardımcı olabilir ..
Mokhamad Rofi'udin

güzel, bunu 5.0 projemde uyguluyorum. Çözüm çok tutarlı görünüyor, ancak herhangi bir sorun geçerse, birkaç hafta sonra olacak.
Ricardo Vigatti

@ MokhamadRofi'udin Çözümünüzü uyguladım, yeni rota rota listesine eklendi, ancak ilgili yöntemin eklenmediği anlaşılıyor. Bir şey mi kaçırıyorum?
Siavosh

@Siavosh sadece yönteminizi denetleyiciye yazın, yani yöntem verilerini ekliyorum (): `genel işlev verileri (İstek $ isteği) {}`
Mokhamad Rofi'udin

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

Bu bir deneyin. GetData () vb gibi ekstra yöntemler koyun .. Bu route.php temiz tutmak benim için çalıştı


Yas bu işe yarıyor. Laravel 5.1 Belgeleri, Route :: resource ve Route :: denetleyicinin birlikte kullanılabileceğinden bahsetmedi, bunun yerine Kaynak Denetleyicilerini Ekleme'den bahsetti. Yani bu karışık. Ama ans, bunların birlikte kullanılabileceğini kanıtladı
Amir

Üzgünüm Hassan Jamal, bu ikisi birlikte çalışmıyor. Şimdi sadece bir yol :: kaynak kullanırsam nasıl bir denetleyici özel bir yazı yöntemi ayarlayabilirsiniz
Amir

3

Laravel'i kullanma> 5 route klasöründeki web.php dosyasını bulun, yöntemlerinizi ekleyin

Tüm bu yöntemleri dizin, göstermek, depolamak, güncellemek, yok etmek için kontrol cihazınızda tek bir satırda route :: resource kullanabilirsiniz.

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

1

Yeni bir yöntem ve bu yönteme bir rota eklemeniz yeterlidir.

Kumandanızda:

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

Ve web rotalarınızda

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

Denetleyicideki yöntemin herkese açık olduğundan emin olun.


-1

Bu da oldukça iyi çalışıyor. Daha fazla rota eklemenize gerek yok, sadece kaynak denetleyicisinin show yöntemini şu şekilde kullanın:

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(){}

Özel hata sayfası atmak için varsayılanı kullanıyorum.


2
Bu gerçek bir kod kokusu gibi geliyor. Denetleyicilerimin birden fazla eylem gerçekleştirmesini istemem.
RonnyKnoxville
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.