Поэтому я решил, что на самом деле я попытаюсь использовать этот причудливый контейнер IoC в Laravel. Я начинаю с Guzzle, но не могу заставить его работать. Возможно, в моем понимании есть пробел. Я действительно ценю любую помощь здесь.
поэтому у меня есть класс для подключения к RESTful Api. Вот пример из этого:
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Client;
use GuzzleHttp\Subscriber\Oauth\Oauth1;
class EtApi {
//you can pass in the model if you wanna
//protected $model;
//client Id
protected $clientId;
//client secret
protected $clientSecret;
//base_uri
protected $getTokenUri;
protected $client;
//build
function __construct(Client $client)
{
$this->client = $client;
$this->clientId = 's0m3R4nd0mStr1nG';
$this->clientSecret = 's0m3R4nd0mStr1nG';
$this->getTokenUri = 'https://rest.api/requestToken';
$this->accessToken = $this->getToken($this->clientId, $this->clientSecret, $this->getTokenUri);
}
}
Я успешно установил и использовал Guzzle, вручную обновив его внутри таких методов, как $ client = new Client (); но это не очень СУХОЙ, и это не правильный способ делать вещи. Поэтому я создал ServiceProvider в app \ Providers \ GuzzleProvider.php. Я убедился, что это было зарегистрировано в app / config / app.php под $providers = ['App\Providers\GuzzleProvider']
, Вот код провайдера:
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use GuzzleHttp\Client;
use GuzzleHttp\Subscriber\Oauth\Oauth1;
class GuzzleProvider extends ServiceProvider {
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
//
$this->app->bind('Client', function () {
return new Client;
});
}
}
Поэтому, когда я пытаюсь получить доступ к моим методам EtApi, при загрузке происходит сбой загрузки (__construct) со следующей ошибкой.
ErrorException in EtApi.php line 23:
Argument 1 passed to App\EtApi::__construct() must be an instance of GuzzleHttp\Client, none given, called in /home/vagrant/webdocs/et_restful_test/app/Http/Controllers/EtConnectController.php on line 23 and defined
Кто-нибудь из вас, Мастера Laravel, имеет представление, почему я не могу связать Guzzle с помощью этого кода, и магия Laravel просто вставит объект в конструктор? [Документы1 скажи, что я должен быть в состоянии сделать это. Я должен что-то упустить. Благодарю вас!
Трудно сказать наверняка, основываясь на информации в вашем вопросе, но основываясь на этом
Аргумент 1, передаваемый в App \ EtApi :: __ construct (), должен быть экземпляром GuzzleHttp \ Client, не указан, вызывается в /home/vagrant/webdocs/et_restful_test/app/Http/Controllers/EtConnectController.php в строке 23 и определен
Звучит так, как будто вы непосредственно создаете App\Eti
класс по строке 23 EtConnectController.php
с кодом, который выглядит примерно так
$api = new App\EtApi;
Если это так, есть ключевой элемент внедрения зависимостей Laravel, который вам не хватает. Laravel не может изменить поведение стандартного PHP — то есть, если вы создаете новый класс со встроенным PHP new
ключевое слово, то у Laravel никогда не будет изменений для добавления каких-либо зависимостей в __construct
,
Если вы хотите воспользоваться внедрением зависимости, вам также необходимо инстанцировать ваш объект через контейнер приложений Laravel. Есть много разных способов сделать это — вот два из них
//$api = new App\EtApi;
\App::make('App\EtApi'); //probably "the right" way
$api = app()['App\EtApi']
Если вы сделаете это, Laravel прочитает подсказки типа в __construct
и попробуйте ввести зависимости для вашего объекта.
Просто измените свою регистрационную функцию на
/**
* Register the application services.
*
* @return void
*/
public function register()
{
//
$this->app->bind('GuzzleHttp\Client\Client', function () {
return new Client;
});
}
Это должно сработать => IOC разрешает fqcn, а не короткий, так что, выставив его в вашем контейнере, вам нужно будет также связать его с fqcn!
Надеюсь, поможет!