试图将Guzzle Curl客户端绑定到larvel 's服务容器——然后键入提示客户端在尝试__constru


Attempting to bind Guzzle Curl Client to Laravel's Service Container -- then Type Hint the Client Fails when attempting to __construct()

所以我想我会尝试在Laravel中实际使用这个花哨的IoC容器。我从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 ();但这不是很DRY,也不是正确的做事方式。所以我在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的魔法只是注入对象到构造函数吗?医生说我应该能做这件事。我一定是漏掉了什么。谢谢你!

根据你问题中的信息很难确定,但是根据这个

参数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 !

希望有帮助!