Laravel Own ServiceProvider客户端调用类型错误:传递给...的参数1必须是

时间:2016-07-01 14:56:57

标签: php laravel

我想换掉我的客户电话或更好我尝试围绕this package创建一个包装器,所以我不必每次都写这个,所以我做了一个新的ServiceProvider应该调用

// Create a new client, 
// so i dont have to type this in every Method
$client = new ShopwareClient('url', 'user', 'api_key');

我发出的每一个请求。

// Later after the Client is called i can make a Request
return $client->getArticleQuery()->findAll();

SwapiServiceProvider

<?php

namespace Chris\Swapi;

use Illuminate\Support\ServiceProvider;
use LeadCommerce\Shopware\SDK\ShopwareClient;

class SwapiServiceProvider extends ServiceProvider
{
    /**
     * Perform post-registration booting of services.
     *
     * @return void
     */
    public function boot()
    {

    }

    /**
     * Register any package services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton(ShopwareClient::class, function () {
            return new ShopwareClient(
                    env('SHOPWARE_URL'),
                    env('SHOPWARE_USER'),
                    env('SHOPWARE_KEY')
                );
        });
    }
}

我的班级

...
use LeadCommerce\Shopware\SDK\ShopwareClient as Shopware;

class Swapi
{
    public function fetchAllArticles(Shopware $shopware)
    {
        return $shopware->getArticleQuery()->findAll();
    }
}

测试

我只是在我的routes.php中调用它进行测试

use Chris\Swapi\Swapi;

Route::get('swapi', function () {
    // Since this is a package i also made the Facade
    return Swapi::fetchAllArticles();
});

但我每次都会得到错误

  

Swapi.php第18行中的FatalThrowableError:输入错误:参数1   传递给Chris \ Swapi \ Swapi :: fetchAllArticles()必须是一个实例   LeadCommerce \ Shopware \ SDK \ ShopwareClient,没有给出,调用   第7行/Users/chris/Desktop/code/swapi/app/Http/routes.php

所以我问为什么这个

return new ShopwareClient(
   env('SHOPWARE_URL'),
   env('SHOPWARE_USER'),
   env('SHOPWARE_KEY')
);
每次我调用一个方法$shopware->getArticleQuery()->findAll();时都不会调用

有谁知道为什么?

1 个答案:

答案 0 :(得分:1)

我认为这里可能会有一些关于Laravel的IoC的混淆。当您使用return Swapi::fetchAllArticles();时,Laravel不知道您在做什么,因为您没有使用容器来构建Swapi类(即使您已经使用容器注册了一个),也不知道有一个外观,以这种方式访问​​它。否则PHP会抱怨,因为你的函数不是static

我刚刚编写了这段代码并验证了它的工作原理就像Laravel将它们放在一起一样。

在我的服务提供商中,我的注册功能就是这个......

public function register()
{
    $this->app->singleton('swapi', function($app) {
        return new SwapiRepository(
            new ShopwareClient(
                env('SHOPWARE_URL'),
                env('SHOPWARE_USER'),
                env('SHOPWARE_KEY')
            )
        );
    });
}

请记住,swapi实际上只是容器用于查找实际类的密钥。当您可以保持简单易用时,无需传递整个合格的类名称。

我的SwapiRepository,它确实是Shopware SDK的包装器。

use LeadCommerce\Shopware\SDK\ShopwareClient;

class SwapiRepository
{
    protected $client;

    public function __construct(ShopwareClient $client)
    {
        $this->client = $client;
    }

    public function fetchAllArticles()
    {
        return $this->client->getArticleQuery()->findAll();
    }
}

此时,你基本上已经完成了。只需在App\Providers\SwapiServiceProvider::class,中添加providers数组(您可能已经完成)app/config.php,然后使用您的包装器......

$swapi = app('swapi');
$swapi->fetchAllArticles();

或者,只要Laravel正在构建所述类,Laravel就可以将其注入其他类。

如果你想为此构建一个外观,以便每次你想要使用它或者使用snytactical sugar时自己保存一行代码......

use Illuminate\Support\Facades\Facade;

class Swapi extends Facade
{
    protected static function getFacadeAccessor() { return 'swapi'; }
}

确保更新aliases中的app/config.php数组,使其包含'Swapi' => App\Repositories\Swapi::class,

最后你应该能够像这样使用它......

Swapi::fetchAllArticles();

请注意您的命名空间与我的不同,因此您可能需要将其替换为您的。您现在也应该能够轻松地将Swapi注入到其他类中,甚至在需要时将注入到控制器中的方法。

请记住,如果你这样做,请确保使用app()函数从Laravel的服务容器中获取这些类的实例。如果您尝试使用new SomeClass自己构建它们,那么您有责任自己注入任何依赖项。