我使用Guzzle:围绕shopify的RESTapi(使用基本身份验证的私有应用程序(创建了一个简单的包装器,如下所示
<?php
namespace AppServices;
use stdClass;
use Exception;
use GuzzleHttpClient as GuzzleClient;
/**
* Class ShopifyService
* @package AppServices
*/
class ShopifyService
{
/**
* @var array $config
*/
private $config = [];
/**
* @var GuzzleClient$guzzleClient
*/
private $guzzleClient;
/**
* ShopifyService constructor.
*/
public function __construct()
{
$this->config = config('shopify');
}
/**
* @return ShopifyService
*/
public function Retail(): ShopifyService
{
return $this->initGuzzleClient(__FUNCTION__);
}
/**
* @return ShopifyService
*/
public function Trade(): ShopifyService
{
return $this->initGuzzleClient(__FUNCTION__);
}
/**
* @param string $uri
* @return stdClass
* @throws GuzzleHttpExceptionGuzzleException
* @throws Exception
*/
public function Get(string $uri): stdClass
{
$this->checkIfGuzzleClientInitiated();;
$result = $this->guzzleClient->request('GET', $uri);
return GuzzleHttpjson_decode($result->getBody());
}
/**
* @throws Exception
*/
private function checkIfGuzzleClientInitiated(): void
{
if (!$this->guzzleClient) {
throw new Exception('Guzzle Client Not Initiated');
}
}
/**
* @param string $storeName
* @return ShopifyService
*/
private function initGuzzleClient(string $storeName): ShopifyService
{
if (!$this->guzzleClient) {
$this->guzzleClient = new GuzzleClient([
'base_url' => $this->config[$storeName]['baseUrl'],
'auth' => [
$this->config[$storeName]['username'],
$this->config[$storeName]['password'],
],
'timeout' => 30,
]);
}
return $this;
}
}
config/shopify.php
如下所示:
<?php
use ConstantsSystem;
return [
System::STORE_RETAIL => [
'baseUrl' => env('SHOPIFY_API_RETAIL_BASE_URL'),
'username' => env('SHOPIFY_API_RETAIL_USERNAME'),
'password' => env('SHOPIFY_API_RETAIL_PASSWORD'),
],
System::STORE_TRADE => [
'baseUrl' => env('SHOPIFY_API_TRADE_BASE_URL'),
'username' => env('SHOPIFY_API_TRADE_USERNAME'),
'password' => env('SHOPIFY_API_TRADE_PASSWORD'),
],
];
当我使用这样的服务时:
$retailShopifySerice = app()->make(AppServicesShopifyService::class);
dd($retailShopifySerice->Retail()->Get('/products/1234567890.json'));
我得到以下错误:
GuzzleHttp\Exception\RequestExceptioncURL错误3:(请参阅https://curl.haxx.se/libcurl/c/libcurl-errors.html)
正如您所看到的,我正在制作一个带有默认选项(用于基本uri+基本auth(的简单的guzzlehttp客户端,并进行后续的GET请求。
这在理论上应该有效,但我不明白为什么会出现这个错误?
我已经验证了配置是否正确(即它具有我期望的值(,并尝试清除所有laravel缓存。
你知道这里可能出了什么问题吗?
由于某种原因,我无法获得base_url
选项来使用GuzzleClient
,所以我用另一种方式解决了它:
<?php
namespace AppServices;
use Exception;
use AppDTOsShopifyResult;
use GuzzleHttpClient as GuzzleClient;
use GuzzleHttpExceptionGuzzleException;
/**
* Class ShopifyService
* @package AppServices
*/
class ShopifyService
{
const REQUEST_TYPE_GET = 'GET';
const REQUEST_TYPE_POST = 'POST';
const REQUEST_TIMEOUT = 30;
/**
* @var array $shopifyConfig
*/
private $shopifyConfig = [];
/**
* ShopifyService constructor.
*/
public function __construct()
{
$this->shopifyConfig = config('shopify');
}
/**
* @param string $storeName
* @param string $requestUri
* @return ShopifyResult
* @throws GuzzleException
*/
public function Get(string $storeName, string $requestUri): ShopifyResult
{
return $this->guzzleRequest(
self::REQUEST_TYPE_GET,
$storeName,
$requestUri
);
}
/**
* @param string $storeName
* @param string $requestUri
* @param array $requestPayload
* @return ShopifyResult
* @throws GuzzleException
*/
public function Post(string $storeName, string $requestUri, array $requestPayload = []): ShopifyResult
{
return $this->guzzleRequest(
self::REQUEST_TYPE_POST,
$storeName,
$requestUri,
$requestPayload
);
}
/**
* @param string $requestType
* @param string $storeName
* @param $requestUri
* @param array $requestPayload
* @return ShopifyResult
* @throws GuzzleException
* @throws Exception
*/
private function guzzleRequest(string $requestType, string $storeName, $requestUri, array $requestPayload = []): ShopifyResult
{
$this->validateShopifyConfig($storeName);
$guzzleClient = new GuzzleClient();
$requestOptions = [
'auth' => [
$this->shopifyConfig[$storeName]['username'],
$this->shopifyConfig[$storeName]['password']
],
'timeout' => self::REQUEST_TIMEOUT,
];
if (count($requestPayload)) {
$requestOptions['json'] = $requestPayload;
}
$response = $guzzleClient->request(
$requestType,
$this->shopifyConfig[$storeName]['baseUrl'] . $requestUri,
$requestOptions
);
list ($usedApiCall, $totalApiCallAllowed) = explode(
'/',
$response->getHeader('X-Shopify-Shop-Api-Call-Limit')[0]
);
$shopifyResult = new ShopifyResult(
$response->getStatusCode(),
$response->getReasonPhrase(),
((int) $totalApiCallAllowed - (int) $usedApiCall),
GuzzleHttpjson_decode($response->getBody()->getContents())
);
$guzzleClient = null;
unset($guzzleClient);
return $shopifyResult;
}
/**
* @param string $storeName
* @throws Exception
*/
private function validateShopifyConfig(string $storeName): void
{
if (!array_key_exists($storeName, $this->shopifyConfig)) {
throw new Exception("Invalid shopify store {$storeName}");
}
foreach (['baseUrl', 'username', 'password'] as $configFieldName) {
if (!array_key_exists($configFieldName, $this->shopifyConfig[$storeName])) {
throw new Exception("Shopify config missing {$configFieldName} for store {$storeName}");
}
}
}
}