尝试将 Guzzle Curl 客户端绑定到 Laravel 的服务容器——然后在尝试 __construct() 时键入提示客户端失败
Attempting to bind Guzzle Curl Client to Laravel's Service Container -- then Type Hint the Client Fails when attempting to __construct()
所以我想我会尝试在 Laravel 中实际使用这个奇特的 IoC 容器。我从 Guzzle 开始,但我无法让它工作。也许我的理解有差距。我真的很感谢这里的任何帮助。
所以我有一个 class 用于连接 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);
}
}
我已经通过在 $client = new Client(); 等方法中手动更新 Guzzle 来成功安装和使用它;但这不是很干,也不是正确的做事方式。所以我在 app\Providers\GuzzleProvider.php 创建了一个 ServiceProvider。我确保它已在 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 的魔法只会将 obj 注入构造函数吗? [文档1 说我应该能够做到这一点。我肯定错过了什么。谢谢!
只需将您的注册功能更改为
/**
* Register the application services.
*
* @return void
*/
public function register()
{
//
$this->app->bind('GuzzleHttp\Client\Client', function () {
return new Client;
});
}
这应该可以解决问题 => IOC 解析 fqcn 而不是短的,所以将它暴露在你的容器中你也需要将它绑定到 fqcn!
希望对您有所帮助!
根据你提问的信息有点难说,但是基于这个
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
听起来您是在 EtConnectController.php
的第 23 行直接实例化您的 App\Eti
class,代码看起来像这样
$api = new App\EtApi;
如果是这样的话,那么您缺少 Laravel 依赖注入的一个关键部分。 Laravel 不能改变标准 PHP 的行为——也就是说,如果你用 PHP 的内置 new
关键字创建一个新的 class,那么Laravel 从来没有更改以在 __construct
中注入任何依赖项。
如果您想利用依赖注入,您还需要通过Laravel的应用程序容器实例化您的对象。有很多不同的方法可以做到这一点——这里有两个
//$api = new App\EtApi;
\App::make('App\EtApi'); //probably "the right" way
$api = app()['App\EtApi']
如果您这样做,Laravel 将读取 __construct
中的类型提示并尝试为您的对象注入依赖项。
所以我想我会尝试在 Laravel 中实际使用这个奇特的 IoC 容器。我从 Guzzle 开始,但我无法让它工作。也许我的理解有差距。我真的很感谢这里的任何帮助。
所以我有一个 class 用于连接 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);
}
}
我已经通过在 $client = new Client(); 等方法中手动更新 Guzzle 来成功安装和使用它;但这不是很干,也不是正确的做事方式。所以我在 app\Providers\GuzzleProvider.php 创建了一个 ServiceProvider。我确保它已在 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 的魔法只会将 obj 注入构造函数吗? [文档1 说我应该能够做到这一点。我肯定错过了什么。谢谢!
只需将您的注册功能更改为
/**
* Register the application services.
*
* @return void
*/
public function register()
{
//
$this->app->bind('GuzzleHttp\Client\Client', function () {
return new Client;
});
}
这应该可以解决问题 => IOC 解析 fqcn 而不是短的,所以将它暴露在你的容器中你也需要将它绑定到 fqcn!
希望对您有所帮助!
根据你提问的信息有点难说,但是基于这个
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
听起来您是在 EtConnectController.php
的第 23 行直接实例化您的 App\Eti
class,代码看起来像这样
$api = new App\EtApi;
如果是这样的话,那么您缺少 Laravel 依赖注入的一个关键部分。 Laravel 不能改变标准 PHP 的行为——也就是说,如果你用 PHP 的内置 new
关键字创建一个新的 class,那么Laravel 从来没有更改以在 __construct
中注入任何依赖项。
如果您想利用依赖注入,您还需要通过Laravel的应用程序容器实例化您的对象。有很多不同的方法可以做到这一点——这里有两个
//$api = new App\EtApi;
\App::make('App\EtApi'); //probably "the right" way
$api = app()['App\EtApi']
如果您这样做,Laravel 将读取 __construct
中的类型提示并尝试为您的对象注入依赖项。