Вызвать метод сервиса через интерфейс Laravel

82
04 апреля 2021, 23:40

Помогите разобраться со следующей задачей.

Есть контроллер PaymentController:

class PaymentController extends Controller implements \App\Services\Payment
{
    public function pay(Payment $obj)
    {
    }
    public function getPaymentStatus(Payment $obj)
    {
    }
}

В нём два метода pay и getPaymentStatus. У них в параметрах есть объект интерфейса.

Вот интерфейс Payment:

interface Payment
{
    public function pay();
    public function getPaymentStatus();
}

И есть два сервиса PayPal и PrivatBank, которые реализуют этот интерфейс:

    class PayPal implements Payment
    {
        public function pay()
        {
           //Реализация
        }
       public function getPaymentStatus()
        {
           //Реализация
        }
    }

    class PrivatBank implements Payment
    {
        public function pay()
        {
           //Реализация
        }
       public function getPaymentStatus()
        {
           //Реализация
        }
    }

Как в контроллере, в методе pay() вызвать реализацию метода pay() из сервиса PayPal или PrivatBank?

У меня есть только вариант - передавать в маршруте ещё и название класса и создавать объект этого класса в методе контроллера.

Answer 1

Как один из примеров, хоть и не самых показательных. Откликается на маршруты типа:

Route::post('/player', 'PlayerController@upload')->name('player.upload');
Route::get('/player', 'PlayerController@download')->name('player.download');

Ну и данные не обязательно могут быть получены из Request - это может быть сессия, куки и так далее. Можете еще какую-нибудь "прокладку" воткнуть, которая будет этим управлять. В примере намерено использован отвлеченный Player, вместо Payment, так как существуют готовые пакеты приема оплаты.

/**
 * config\app.php
 */
'providers' => [
  ...
  App\Providers\PlayerServiceProvider::class,
];

/**
 * app\Providers\PlayerServiceProvider.php
 */
namespace App\Providers;
use App\Services\Player\AudioPlayer;
use App\Services\Player\VideoPlayer;
use App\Services\Contracts\PlayerServiceInterface;
use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;
class PlayerServiceProvider extends ServiceProvider
{
  /**
   * Indicates if loading of the provider is deferred.
   *
   * @var bool
   */
  protected $defer = true;
  /**
   * Register services.
   *
   * @return void
   */
  public function register()
  {
    $this->registerPlayerService();
  }
  protected function registerPlayerService()
  {
    $player = $this->app->make('request')->get('player');
    $this->app->singleton(PlayerServiceInterface::class, function ($app) use ($player) {
      if ('video' === $player) {
        return new VideoPlayer();
      }
      return new AudioPlayer();
    });
  }
  /**
   * Get the services provided by the provider.
   *
   * @return array
   */
  public function provides()
  {
    return [PlayerServiceInterface::class];
  }
}

/**
 * app\Http\Controllers\PlayerController.php
 */
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Services\Contracts\PlayerServiceInterface;
class PlayerController extends Controller
{
  protected $player;
  public function __construct(PlayerServiceInterface $player)
  {
    $this->player = $player;
  }
  public function upload(Request $request)
  {
    dd($this->player->upload());
  }
  public function download(Request $request)
  {
    dd($this->player->download());
  }
}

/**
 * app\Services\Contracts\PlayerServiceInterface.php
 */
namespace App\Services\Contracts;
Interface PlayerServiceInterface
{
  public function upload();
  public function download();
}

/**
 * app\Services\Player\AudioPlayer.php
 */
namespace App\Services\Player;
use App\Services\Contracts\PlayerServiceInterface;
class AudioPlayer implements PlayerServiceInterface
{
  public function upload()
  {
    return 'Реализация метода upload() сервиса AudioPlayer.';
  }
  public function download()
  {
    return 'Реализация метода download() сервиса AudioPlayer.';
  }
}

/**
 * app\Services\Player\VideoPlayer.php
 */
namespace App\Services\Player;
use App\Services\Contracts\PlayerServiceInterface;
class VideoPlayer implements PlayerServiceInterface
{
  public function upload()
  {
    return 'Реализация метода upload() сервиса VideoPlayer.';
  }
  public function download()
  {
    return 'Реализация метода download() сервиса VideoPlayer.';
  }
}
READ ALSO
Syntax error, unexpected T_VARIABLE

Syntax error, unexpected T_VARIABLE

В чём может быть моя ошибка?

80
ImageMagick: как правильно ужать картинку?

ImageMagick: как правильно ужать картинку?

Необходимо с помощью ImageMagick обрезать фотографии по умному, то есть если фотография высокая по вертикали, то нужно при указании размера, скажем...

114
Регулярное выражение для preg_replace которое срабатывает на обратный слеш (“\”)

Регулярное выражение для preg_replace которое срабатывает на обратный слеш (“\”)

подскажите, пожалуйста, правильное регулярное выражение для preg_replace в PHP

88
Как сохранить созданное изображение в папку на сервере?

Как сохранить созданное изображение в папку на сервере?

Есть вот такой код, который меняет размер у фотографии, как мне сохранить его в указанную папку?

82