Php Laravel编程接口的最佳方法

Php Laravel编程接口的最佳方法,php,laravel,interface,laravel-5.3,Php,Laravel,Interface,Laravel 5.3,我需要一个关于编程接口的方法的建议 情景: 我需要实现一个伪类ImageUploader,然后在构造函数上接收一个接口,并将图像保存在我的目录中。这是为了学习,所以如果我做得正确,我需要你的建议: 以下是我在Laravel 5.3框架上的实现: 1:虚拟接口实现,以便我可以创建不同的方式来存储我的图像 //dummy interface namespace App\Lib\ImageUploader\Drivers; interface ImageInterface { public

我需要一个关于编程接口的方法的建议

情景: 我需要实现一个伪类ImageUploader,然后在构造函数上接收一个接口,并将图像保存在我的目录中。这是为了学习,所以如果我做得正确,我需要你的建议:

以下是我在Laravel 5.3框架上的实现:

1:虚拟接口实现,以便我可以创建不同的方式来存储我的图像

//dummy interface

namespace App\Lib\ImageUploader\Drivers;

interface ImageInterface
{
   public function hello();
}
2:这里有两个实现我的接口的驱动程序。在现实生活中,每个类都有自己的方法hello,例如,对于任何类型的驱动程序,每个类都可能有自己的save方法

// Avatar Driver Class

namespace App\Lib\ImageUploader\Drivers;

class AvatarImage implements ImageInterface
{
     public function hello()
     {
          return 'I am a AvatarImage';
     }
}
还有一个类,例如BackgroundImage可以保存用户上传的桌面和手机版本的图像:

// Background Driver Class


namespace App\Lib\ImageUploader\Drivers;

class BackgroundImage implements ImageInterface
{
   public function hello()
   {
     // this is a dummy method, in real life this class will save 2 images (desktop + mobile)
     return 'I am a BackgroundImage';
   }

}
这是我的ImageUploader类,具有编程到接口策略:

// ImageUploader.php
// this class will implement all methods that I need for manage saving operations

namespace App\Lib\ImageUploader;
use App\Lib\ImageUploader\Drivers\ImageInterface;


class ImageUploader
{

   protected $driver;

   public function __construct(ImageInterface $driver)
   {
      $this->driver = $driver;
   }

   public function save()
   {
      return  $this->driver->hello();
   }
}
现在,我创建了自己的Laravel framework服务提供商:

namespace App\Providers;

use App\Lib\ImageUploader\Drivers\AvatarImage;
use App\Lib\ImageUploader\Drivers\BackgroundImage;
use App\Lib\ImageUploader\ImageUploader;
use Illuminate\Support\ServiceProvider;

class ImageUploadServiceProvider extends ServiceProvider
{
    /**
    * Bootstrap the application services.
    *
    * @return void
    */
    public function boot()
   {
     //
   }

    /**
    * Register the application services.
    *
    * @return void
    */

    public function register()
    {
       $this->registerAvatar();
       $this->registerBackground();
    }

    protected function registerAvatar(){
       $this->app->bind('AvatarUploader', function () {
          return new ImageUploader(new AvatarImage());
       });
    }

    protected function registerBackground(){
       $this->app->bind('BackgroundUploader', function () {
         return new ImageUploader(new BackgroundImage());
       });
    }
}
最后,我尝试在我的控制器中使用我的类,例如,当用户尝试上载你的化身图像或新的背景图像时:

// this will produce "I am a AvatarImage" in real life this line create thumbnail and will save my image in my local directory

public function store(Request $request){
    (App::make('AvatarUploader'))->save();   
}
有更好的办法吗?对我的实施有什么建议吗?

请查看和

因此,在服务提供商逻辑中,您可以指定-

$this->app->when(AvatarController::class)
          ->needs(ImageInterface::class)
          ->give(function () {
              return new AvatarUploader();
          });

$this->app->when(BackgroundController::class)
          ->needs(ImageInterface::class)
          ->give(function () {
              return new BackgroundImage();
          });
然后,在控制器或其他类中,只需依赖注入ImageInterface接口,而不是具体的类

class AvatarController extends Controller
{
    protected $imageInterface;
    public function __construct(ImageInterface $imageInterface)
    {
        $this->imageInterface = $imageInterface;
    }

    public function store()
    {
        return $this->imageInterface->hello(); // returns "I am an Avatar Image"
    }
}

class BackgroundController extends Controller
{
    protected $imageInterface;
    public function __construct(ImageInterface $imageInterface)
    {
        $this->imageInterface = $imageInterface;
    }

    public function store()
    {
        return $this->imageInterface->hello(); // returns "I am a Background Image"
    }
}

您好,我不明白我在服务提供商中的方法和您在何时…需要…给予…方面的方法有什么不同。。。。我需要创建两个独立的控制器化身和背景控制器?在我的版本中,您注入的是契约而不是具体的类。这样,您就可以将控制器运行的实现的责任从控制器中移开。然而,您的实现是不同的,因为您实际上是在为新的ImageUploadernew AvatarImage创建一个别名,并简单地称之为AvatarUploader。您正在创建一个快捷方式,而不是分离关注点。在我看来,您的版本可能会增加复杂性,但没有什么好处,因为您也可以在没有服务提供商的情况下注入具体的类;thx Gavy但现在我必须创建两个控制器Avatar和BackgroundController,不是吗?好的,我已经创建了两个控制器AvatarController和BackgroundController,但我需要在我的用户控制器中使用默认的laravel用户控制器如何实现?我需要用一个方法将它传递给UsersController?