- bounty将在6天后过期**。回答此问题可获得+50声望奖励。Jonathon Philip Chambers希望引起更多人对此问题的关注:即使是一个线索或洞察力,导致我发现正确的答案对我自己是值得的绿色勾选。
这是我第一次使用curl_multi_init()
,所以我可能误解了一些东西。学习正确使用它对我来说比解决我的问题更重要,因为这个特殊的函数将解决我未来的许多问题。
这个特殊的调用是为了上传Etsy的照片。Etsy文档在这里。
它在Postman中运行良好。postman为"PHP-cURL"生成的代码片段运行良好。即使在我编辑它之后,它仍然运行良好。
问题是,我有超过1000张高分辨率的图片要上传,所以从头到尾运行整个代码片段,然后循环1000次,无论我的php.ini设置有多慷慨,都会超时。
所以,我一行一行地将现有代码与同步代码段合并,我一定是做错了什么。这个例子几乎完全是实时代码。我只是删除/简化了不相关的内容和个人信息。(希望我没有删除/简化bug。):
<?php
include_once 'databaseStuff.php';
include_once 'EtsyTokenStuff.php';
$result = mysqli_query($conn, "SELECT product, listing_id, alt_text, dataStuff;");
$multiCurl = [];
$multiResult = [];
$multiHandle = curl_multi_init();
if (mysqli_num_rows($result) > 0){
while ($row = mysqli_fetch_assoc($result)){
for($image = 1; $image <=2; $image++){
$multiCurl[$row['product'] . "_" . $image] = curl_init();
curl_setopt_array($multiCurl[$row['product'] . "_" . $image],
array(
CURLOPT_URL => "https://openapi.etsy.com/v3/application/shops/$myShopNumber/listings/" . $row['listing_id'] . "/images",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => array(
"image" => new CURLFILE(
[
1 => "img/imagePathStuff/" . $row['product'] . ".jpg",
2 => "img/differentImagePathStuff/" . $row['product'] . ".jpg"
][$image]
),
// "listing_image_id" =>,
"rank" => $image,
"overwrite" => true,
// "is_watermarked" =>,
"alt_text" => $row['alt_text']
),
CURLOPT_HTTPHEADER => array(
"x-api-key: $myAPIKey",
"authorization: Bearer {$etsyAccessToken}"
),
)
);
curl_multi_add_handle($multiHandle, $multiCurl[$row['product'] . "_" . $image]);
}
}
$index = null;
do {
curl_multi_exec($multiHandle, $index);
} while($index > 0);
foreach($multiCurl as $k => $curlHandle){
$multiResult[$k] = curl_multi_getcontent($curlHandle);
curl_multi_remove_handle($multiHandle, $curlHandle);
}
curl_multi_close($multiHandle);
}
一旦它开始工作,我可能会把它分成函数块,但我更喜欢以这种格式编辑损坏的代码,并在以后添加函数调用。
由于以前从未使用过这些函数,我不确定它们应该如何工作,但我注意到的行为是:
- 所有代码执行,从头到尾,没有致命错误。
- do-while循环执行一次,然后再循环一次(也许它应该这样做,也许它应该为每张照片循环一次,但在任何地方都无法澄清这一点)。
- 它应该更新照片,不幸的是,第一次测试是在非常小的编辑,但再次尝试包括一个故意错误的照片,我至少知道,该特定的照片没有更新,所以可能没有更新。
curl_multi_getcontent($curlHandle)
始终返回空字符串curl_multi_exec($multiHandle, $index)
总是返回0(之前声称它是1002是不正确的。1002实际上是运行函数后第二个参数$index
的值。)- 这个调用通常会对201有非常详细的响应,并且至少会返回400、401、403、404、409和500的错误,但是我认为我的代码甚至还没有深入到进行调用的程度,我甚至还没有弄清楚如何获得响应代码。
- 对于一个从我的服务器向Etsy的服务器传输超过1000张高分辨率图像的脚本来说,它的执行速度当然非常快。
$multiHandle
似乎按预期工作。至少,var_dump($multiHandle)
显示了其中所有正确的文件名。
我已经因为这个问题损失了整整一天的工作时间,但是如果是一个小的打字错误造成的,我也不会感到惊讶。
1条答案
按热度按时间y1aodyip1#
这只是一种猜测,但是如果您的问题是超时,那么您编写的以下循环可能就是问题所在:
您正在重复调用
curl_multi_exec
,这会在您等待所有上传完成的同时消耗CPU。您应该只定期检查上传状态,并在其间进入等待状态。这应该会减少您的总CPU时间: