В моем приложении Symfony 4 мне нужно иметь несколько контроллеров, каждый для монтирования / группировки различных конечных точек API в разных префиксах.
Каждому контроллеру необходимо сначала инициализировать и установить в свойстве класса клиент API, а также установить учетные данные. Чтобы избежать повторения кода во всех из них, я хотел бы создать BaseController, чтобы другие могли расширять и напрямую обращаться или иметь доступное свойство client со всем, что ему нужно.
Базовый контроллер:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Vendor\ApiClient;
class BaseApiController extends Controller
{
/**
* @var ApiClient
*/
protected $apiClient;
public function __construct( array $apiClientCredentials, ApiClient $apiClient )
{
$this->apiClient = $apiClient;
$this->apiClient->credentials($apiClientCredentials['id'], $apiClientCredentials['main_password']);
}
}
Один из многих похожих контроллеров, у которых я хочу, чтобы свойство API было готово к вызову / использованию:
<?php
namespace App\Controller;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
/**
* Account endpoints
* @Route("/account")
*/
class AccountApiController extends BaseApiController
{
/**
* Get the balance.
* @Route("/balance", name = "balance")
*/
public function balance()
{
return new JsonResponse($this->apiClient->getBalance());
}
}
Это то, что у меня есть, но все еще не работает должным образом, и мне интересно, как лучше всего собрать эту настройку?
Обновлено: это сообщение об ошибке, которое я получаю.
Cannot autowire service "App\Controller\AccountApiController": argument "$apiClientCredentials" of method "App\Controller\BaseApiController::__construct()" must have a type-hint or be given a value explicitly.
Обновлено: добавление моего services.yaml
# config/services.yaml
parameters:
app.creds:
id: '%env(ACCOUNT_ID)%'
main_password: '%env(ACCOUNT_MAIN_PASSWORD)%'
# ...
services:
_defaults:
autowire: true
# ...
App\Controller\BaseApiController:
arguments:
$apiClientCredentials: '%app.creds%'






Объем вашего APiClient должен быть защищен
/**
* @var ApiClient
*/
protected $apiClient;
Поскольку я собираюсь использовать его в нескольких контроллерах, сейчас кажется справедливым просто привязать аргумент.
services:
_defaults:
autowire: true
autoconfigure: true
public: false
bind:
$walletCreds: '%app.wallet_creds%'
Также базовый класс должен быть абстрактным:
abstract class BaseApiController extends Controller
{
//...
Вы правы, у меня был неправильный прицел для
$apiClient, теперь я изменил его в своем коде наprotected. Однако это не причина и не решение моего вопроса. См. Сообщение об ошибке, которое я добавил выше, если это помогает дать больше контекста.