Magento - API库存数量更新(SLOW AS HELL)

时间:2012-03-01 17:36:58

标签: api magento csv product

我正在使用Magento API来更新库存,但我正在使用CSV导出的产品包含magento中存在的产品skus和不存在的产品skus

所以当sku列表为3长时,它可以正常工作。

当它长达8k +时它会断裂。例如它chuggs和wurrs然后'php white screen of death'

我的代码也阻止了特殊的skus没有被输入(不要问)他们都是pre_match的东西。

所以我的代码看起来像这样:

    $proxy = new SoapClient('http://www.magentosite/index.php/api/?wsdl');
$sessionId = $proxy->login('user', 'apikey');


if (($handle = fopen("../stock.csv", "r")) !== FALSE) {
        while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {


            if(count($proxy->call($sessionId, 'product_stock.list', $data[1])) > 0 && (preg_match('/specialcode1/', $data[1]) || preg_match('/^specialcode2/i', $data[1]) || preg_match('/specialcode3/', $data[1]))){

                        $proxy->call($sessionId, 'product_stock.update', array($data[1], array('qty'=>$data[2])));

            }

}
}
fclose($handle);





echo 'complete';

所以我理解API可能非常慢,它触摸木头似乎完成到最后的sku但仍然会引发白色php错误。

关于我的代码是垃圾还是仅仅是API的性质的任何想法?

问候 安迪。

1 个答案:

答案 0 :(得分:7)

每个API调用都有很大的开销,即Magento广泛的OOP系统。通过一些思考,可以减少呼叫次数。

if (($handle = fopen("../stock.csv", "r")) !== FALSE) {
    $qtyBySku = array();
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
        // first column ($data[0]) is ignored.
        list(, $sku, $qty) = $data;
        $qtyBySku[$sku] = (float) $qty;
    }
    fclose($handle);

    $skus = preg_grep('/specialcode1|^specialcode2|specialcode3/',
                array_keys($qtyBySku));
    if ($skus) try {
        $proxy = new SoapClient('http://www.magentosite/index.php/api/?wsdl');
        $sessionId = $proxy->login('user', 'apikey');

        // Break into blocks of 100 because it's TOO efficient
        foreach (array_chunk($skus, 100) as $skuChunk) {
            $stock = $proxy->call($sessionId, 'product_stock.list',
                         array($skuChunk));
            if ($stock) {
                $calls = array();
                foreach ($stock as $product) {
                    $sku = $product['sku'];
                    $qty = $qtyBySku[$sku];
                    $calls[] = array(
                        'product_stock.update', array($sku, array(
                            'qty' => $qty,
                            // only in stock if qty is high enough
                            'is_in_stock' => $qty > 0
                        ))
                    );
                }
                $proxy->multiCall($sessionId, $calls);
            }
        }
        $proxy->endSession($sessionId);

        echo 'complete';
    }
    catch (SoapFault $err) {
        echo $err;
        // or do something more interesting here
    }
    // else nothing to update
}

请注意一些常识性变化:

  • 在登录API之前打开和关闭文件,可以快速检查文件并慢速建立网络连接。
  • product_stock.list之前检查SKU是否有特殊代码,如果有任何SKU匹配则只有登录。同样,本地工作比远程工作更快。
  • 使用单个正则表达式而不是多个,preg_grep仅解析表达式一次,而不是每个记录一次。
  • product_stock.list获取一系列ID或SKU,这意味着您可以一次查找所有记录。
  • 您无需等待product_stock.update返回值(尽管它有一个),这意味着您可以在multiCall中一次执行多项操作。