php - Laravel Guzzle - cURL 错误 3:(参见 https://curl.haxx.se/libcurl/c/libcurl-errors.html)
问题描述
我使用 Guzzle 围绕 shopify 的 REST api(使用基本身份验证的私有应用程序)创建了一个简单的包装器:
<?php
namespace App\Services;
use stdClass;
use Exception;
use GuzzleHttp\Client as GuzzleClient;
/**
* Class ShopifyService
* @package App\Services
*/
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 \GuzzleHttp\Exception\GuzzleException
* @throws Exception
*/
public function Get(string $uri): stdClass
{
$this->checkIfGuzzleClientInitiated();;
$result = $this->guzzleClient->request('GET', $uri);
return \GuzzleHttp\json_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 Constants\System;
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(\App\Services\ShopifyService::class);
dd($retailShopifySerice->Retail()->Get('/products/1234567890.json'));
我收到以下错误:
GuzzleHttp\Exception\RequestException cURL 错误 3:(参见https://curl.haxx.se/libcurl/c/libcurl-errors.html)
如您所见,我正在使用默认选项(用于基本 uri + 基本身份验证)制作一个简单的 guzzle http 客户端并发出后续 GET 请求。
这在理论上应该可行,但我不知道为什么会抛出这个错误?
我已经验证了配置是否正确(即它具有我期望的值)并尝试清除所有 laravel 缓存。
任何想法这里可能有什么问题?
解决方案
由于某种原因,我无法base_url
选择使用,所以我以不同的方式解决了它:Guzzle\Client
<?php
namespace App\Services;
use Exception;
use App\DTOs\ShopifyResult;
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Exception\GuzzleException;
/**
* Class ShopifyService
* @package App\Services
*/
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),
\GuzzleHttp\json_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}");
}
}
}
}
推荐阅读
- apache - 两个站点的 Apache 虚拟主机无法正常工作
- hyperledger-fabric - 有没有办法在超级账本结构中获取用户私钥和公钥以进行数据加密
- git - 如何在不下载所有文件的情况下将现有 Git 链接到当前环境?
- azure-data-lake - azure blob 存储和 azure 数据湖存储之间的区别
- javascript - 如果选中复选框,如何对文本进行换行
- html - 为什么我的粘性定位不起作用?
- java - 如何从文本文件中获取二维数组,并使用 charAt 将其“复制”到另一个数组中
- android - 如何在kotlin中从iso转换格式日期
- ios - FCM 与 Xamarin iOS 的集成
- postgresql - 如何在只读事务中不执行 INSERT