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


PHP script returning 500 error - Using cURL to send to API

我正在与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";

?> 

看起来您有一个错误(可能只是问题中的拼写错误?)

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通常意味着"我们的服务器无法处理请求"。如果他们能修改它来处理这种情况,并向您发送一个200响应,其中包含一个有效负载的组件,指示任何无法处理的项目,并通过某种类型的相关标识符进行索引,那就太好了。

当我使用CLI运行该脚本时,该脚本已完成。我只是好奇为什么会这样?我想这与内存使用有关吗?这是正确的吗?如果我设置了一个cron来执行此操作,那么cron基本上也使用CLI吗?