PHP脚本返回500错误 - 使用cURL发送到API

时间:2014-10-24 19:35:52

标签: php api curl

我正在使用API​​来更新我们的产品信息。 API允许我每次调用大量项目上传20个项目。为了更新所有1000多个项目,我必须多次遍历此脚本。这个脚本基本上编译了20个项目的XML,并使用curl发送它,然后抓取接下来的20个项目创建XML并重复。当我将outter循环限制为15时,它工作正常并返回每个API调用的成功消息。它在随机时间失败我在失败之前发送了多达40个API调用,并且在10次调用后我也失败了。

我无法在错误日志中找到任何关于我为什么得到500回来的内容。 我已经联系了管理API的人,看看他们是否有任何想法。

我最好的猜测是它与超时有关。

$query = "SELECT DISTINCT 
`id`,
`link`, 
`price`, 
`ship_group`,
`fixed_ship`, 
`do_not_sell`, 
`shipping_weight`, 
`shipping_length`, 
`shipping_width`, 
`shipping_height`, 
`title`, 
`brand`, 
`inventory`, 
`available`,
`type`,
`min_order_qty`,  
`image`, 
`call`, 
`allow_in_cart`, 
`allow_backorder` FROM $table WHERE `id` > 10001 AND `price` > 0 AND `base_match` = 'm' ORDER BY `id`";

$resultID = mysql_query($query, $linkID) or die(mysql_error());

//total number of rows divided by 20 rounded up to nearest whole number
//call createItems that amount of times 
$cycles =  ceil(mysql_num_rows($resultID) / 20);


$i = 0;
while( $i < 20 ){
//tried sleeping between calls but this didnt help
    sleep(2);
$i++;

$x = 0;
  $xml_output = "\t<items>\n";
    while( $x < 20){
        $row = mysql_fetch_assoc($resultID);
        $x++;

    $itemArray[$x]['id'] = $row['id'];
        if ($itemArray[$x]['id'] == "") {
            break;  
         };
    $itemArray[$x]['link'] = $row['link'];
    $itemArray[$x]['price'] = $row['price'];
    $itemArray[$x]['ship_group'] = $row['ship_group'];
    $itemArray[$x]['fixed_ship'] = $row['fixed_ship'];
    $itemArray[$x]['do_not_sell'] = $row['do_not_sell'];
    $itemArray[$x]['shipping_weight'] = $row['shipping_weight'];
    $itemArray[$x]['shipping_length'] = $row['shipping_length'];
    $itemArray[$x]['shipping_width'] = $row['shipping_width'];
    $itemArray[$x]['shipping_height'] = $row['shipping_height'];
    $itemArray[$x]['title'] = $row['title'];
    $itemArray[$x]['brand'] = $row['brand'];
    $itemArray[$x]['inventory'] = $row['inventory'];
    $itemArray[$x]['type'] = $row['type'];
    $itemArray[$x]['min_order_qty'] = $row['min_order_qty'];
    $itemArray[$x]['available'] = $row['available'];
    $itemArray[$x]['image'] = $row['image'];
    $itemArray[$x]['call'] = $row['call'];
    $itemArray[$x]['allow_in_cart'] = $row['allow_in_cart'];
    $itemArray[$x]['allow_backorder'] = $row['allow_backorder'];

    $desc = htmlspecialchars_decode($itemArray[$x]['title']);
    $desc = str_replace('"',"'", $desc);
    $desc = str_replace('&',"and", $desc);
    $desc = str_replace('%',"%25", $desc);

    $track_inventory = (strtolower($itemArray[$x]['inventory']) == "i") ? true : false;
    $allow_backorder = ($itemArray[$x]['allow_backorder'] == 0)? true : false;

    $cost = $itemArray[$x]['price'];

    if ($itemArray[$x]['do_not_sell'] == 1) {
        $inactive = true;
        $cost = 0.00;
    } else if (!$allow_backorder && $itemArray[$x]['available'] <= 0) {
        $cost = 0.00;
        $inactive = true;
    } else if ($itemArray[$x]['call'] == 1 ) {
        $cost = 0.00;
            $inactive = true;
        } else if  ($itemArray[$x]['allow_in_cart'] == 0) {
            $inactive = true;
            // call is set to no
            // allow in cart set to no
            // shows price but dont allow in cart
        } else if ($track_inventory && $itemArray[$x]['available'] <= 0) {
            $inactive = false;
            //allow in cart but
            //display shipping delay message
            //do nothing in UC  
        } else {
            $inactive = false;
        };

    $xml_output .= "\t\t<item>\n";
    $xml_output .= "\t\t\t<merchant_item_id>".$itemArray[$x]['id']."</merchant_item_id>\n";
    $xml_output .= "\t\t\t<description>".$desc."</description>\n";
    $xml_output .= "\t\t\t<view_url>".htmlspecialchars($itemArray[$x]['link'])."</view_url>\n";
    $xml_output .= "\t\t\t<cost>".number_format($cost, 2, '.', '')."</cost>\n";
    $xml_output .= "\t\t\t<uom_weight>LB</uom_weight>\n";
    $xml_output .= "\t\t\t<weight>".number_format($itemArray[$x]['shipping_weight'], 2, '.', '')."</weight>\n";
    $xml_output .= "\t\t\t<inactive>".var_export($inactive, true)."</inactive>\n";  
    $xml_output .= "\t\t\t<minimum_quantity>".$itemArray[$x]['min_order_qty']."</minimum_quantity>\n";  
    $xml_output .= "\t\t\t<inventory_quantity>".$itemArray[$x]['available']."</inventory_quantity>\n";  
    $xml_output .= "\t\t\t<track_inventory>false</track_inventory>\n";      
    $xml_output .= "\t\t\t<manufacturer_name>".htmlspecialchars($itemArray[$x]['brand'])."</manufacturer_name>\n";
    $xml_output .= "\t\t\t<manufacturer_sku></manufacturer_sku>\n";
    $xml_output .= "\t\t\t<uom_distance>IN</uom_distance>\n";

    // if its a solar panel or if it weighs over 70lbs remove dimensions
    //add per dustins request - "should fix panel shipping errors"
    if (strtolower($itemArray[$x]['type']) == "solar panel" || $itemArray[$x]['shipping_weight'] >= 70) {
        $xml_output .= "\t\t\t<length>0</length>\n";
        $xml_output .= "\t\t\t<width>0</width>\n";
        $xml_output .= "\t\t\t<height>0</height>\n";    
    } else {
        $xml_output .= "\t\t\t<length>".number_format($itemArray[$x]['shipping_length'], 2, '.', '')."</length>\n";
        $xml_output .= "\t\t\t<width>".number_format($itemArray[$x]['shipping_width'], 2, '.', '')."</width>\n";
        $xml_output .= "\t\t\t<height>".number_format($itemArray[$x]['shipping_height'], 2, '.', '')."</height>\n";
    }
    $xml_output .= "\t\t\t<froogle>\n";
    $xml_output .= "\t\t\t\t<image_url>".$itemArray[$x]['image']."</image_url>\n";
    $xml_output .= "\t\t\t</froogle>\n";
    $xml_output .= "\t\t\t<shipping>\n";
    if ($itemArray[$x]['ship_group'] == strtolower('fixed') && $itemArray[$x]['fixed_ship'] == 0) {
        $xml_output .= "\t\t\t\t<free_shipping>true</free_shipping>\n";
    } elseif ($itemArray[$x]['ship_group'] == strtolower('freight')) {
        $xml_output .= "\t\t\t\t<methods>\n";
        $xml_output .= "\t\t\t\t\t<method>\n";
        $xml_output .= "\t\t\t\t\t\t<name>Con-way: LTL</name>\n";
        $xml_output .= "\t\t\t\t\t\t<validity>valid only for</validity>\n";
        $xml_output .= "\t\t\t\t\t</method>\n";
        $xml_output .= "\t\t\t\t</methods>\n";
    } else {
        $xml_output .= "\t\t\t\t<free_shipping>false</free_shipping>\n";
    }
    $xml_output .= "\t\t\t</shipping>\n";               
    $xml_output .= "\t\t</item>\n";
}

$xml_output .= "\t</items>\n";

//open XML and write 20 items into it.
$fh = fopen('./bulk-item-pusher.xml','w') or die($php_errormsg);
fwrite($fh, $xml_output) or die($php_errormsg);
fclose($fh);

$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, "theapiurl");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "merchantId=".$merchId."&login=".$login."&password=".$password."&function=".$function."&Items=".$xml);
$content=curl_exec($ch);
if(curl_errno($ch)) {
    $err = curl_error($ch);
    $ef = fopen('./last-item.xml','w') or die($php_errormsg);
    fwrite($ef, $err) or die($php_errormsg);
    break;
}
curl_close($ch);

echo htmlspecialchars($content ." " . $itemArray[$x]['id'])."<br />";
}
echo "finished";


?> 

2 个答案:

答案 0 :(得分:1)

看起来你有一个错误(可能只是你问题中的错字?)

curl_setopt($ch, CURLOPT_POSTFIELDS, "merchantId=".$merchId."&login=".$login."&password=".$password."&function=".$function."&Items=".$xml);

$xml应该是$xml_output吗?另外,除非您稍后在其他地方使用它,否则为什么要写入./bulk-item-pusher.xml

添加错误处理以检查远程API的错误响应

// Handle cURL error
if(curl_errno($ch)) {
    $err = curl_error($ch);
    $ef = fopen('./last-item.xml','w') or die($php_errormsg);
    fwrite($ef, $err) or die($php_errormsg);
    break;
}
// Handle error response from API
elseif(curl_getinfo($ch, CURLINFO_HTTP_CODE) === '500') {
    // Take note of which 20 records were sent to cause this error.
    // They need to be analyzed more deeply to determine which one caused
    // the remote service to crap out
}

既然你说超时似乎不是问题,那么我将在上面发表第二篇@Jay Blanchard的评论;它可能是您在某些请求中发送的数据。

此时我会收集已发送的20个项目中的每一个并单独发送,以确定您发送的其中一个项目是否导致远程方崩溃。

从那里确定该特定数据项的问题。一旦你弄清楚了,我还会与那些维护该API的人进行一些沟通。 500&#39; s通常意味着&#34;我们的服务器无法应对请求&#34; 。如果他们可以修改它以处理这种情况并向你发回200响应,其中包含有效负载的一个组成部分,指示任何无法处理的项目,并通过某种类型的相关标识符索引,那将是很好的。

答案 1 :(得分:1)

当我使用CLI运行脚本时,脚本已完成。我只是好奇为什么会这样?我的猜测是它必须对内存使用做些什么?那是对的吗?如果我设置一个cron来执行此操作,cron基本上也使用CLI吗?