更新数据库中成千上万个条目的价格和库存

时间:2018-08-19 20:48:07

标签: php mysqli

我正在研究一个项目,该项目根据自动售货程序中的数据更新prestashop中的产品数据库(价格和库存)。我正在使用PHP代码和与数据库的MySQL连接进行此操作。

问题是大约有58.000个产品,更新所有产品似乎花费很长时间。

这是我的代码:

<?php   

$host = '127.0.0.1';
$uname = '*******';
$pwd = '*******';
$db = "*******";

$con = mysqli_connect($host,$uname,$pwd,$db) or die("connection failed");

echo 'Updating init...' . "<br>";

//Create an instance of the class Update to get and update the data
$update = new Update();

try
{
    // Get the product list from prestashop's DB
    $productsFromPS = $update->getProductListFromPS($con);

    // Cycle through all the product IDs
    foreach ($productsFromPS as $product)
    {
        // Id of the product
        $id = (int) $product['id_product'];

        // Price from PS
        $pricePS = (float) $product['price'];

        // Get the product's stock from PS
        $stockPS = $update->getProductStockFromPS($con, $id);

        // Physical and reserved quantities in PS
        $physQty = $stockPS['physical_quantity'];
        $resQty = $stockPS['reserved_quantity'];

        // Get product's price and stock from Vendus
        $priceAndStockVendus = $update->getPriceAndStockFromVendus($id);

        // Price from Vendus
        $priceVendus = (float) $priceAndStockVendus[0];

        // Tools for float compardsion
        $zero = (float) 0.00;
        $epsilon = (float) 0.00001;

        // If the price in Vendus is 0, put 0 to stock in PS
        if(!(abs($priceVendus-$zero) < $epsilon))
            $stockVendus = (int) $priceAndStockVendus[1];
        else
            $stockVendus = 0;~

        // If the prices do not match, update price
        if(!(abs($pricePS-$priceVendus) < $epsilon))
            $update->updatePrice($con, $id, $priceVendus);

        // If the stocks do not matcth, update stock
        if ($stockVendus!=$physQty)
            $update->updateStock($con, $id, $stockVendus, $resQty);
    }
}
catch (Exception $ex) {
    // Shows a message related to the error
    echo 'Other error: <br />' . $ex->getMessage();
}

/*
    Class which method to get and update data
*/
class Update
{
   public function getProductListFromPS ($con)
    {
        try
        {
            $sql_q = mysqli_query($con,"SELECT `id_product`, `price` FROM `ps_product` ORDER BY `id_product` ASC");
            $output = "";

            if($sql_q)
            {
                while($result = mysqli_fetch_assoc($sql_q))
                {
                    $output[] = $result;
                    //echo $result['id_product'] . "<br>";
                }

                if($output)
                {
                    //echo '4: ' . $output[4]['id_product'] . "<br>";
                }
                else
                {
                    echo "empty ressult set <br>";
                }
            }
            else
            {
                echo 'Invalid query: ' . mysqli_error() . "<br>";
            }

            return $output;
        }
        catch (Exception $ex) {
            // Shows a message related to the error
            echo 'Error: <br />' . $ex->getMessage() . '<br>';
        }

    }

    public function getProductStockFromPS ($con, $id)
    {
        try
        {
            $sql_q = mysqli_query($con,"SELECT `quantity`, `physical_quantity`, `reserved_quantity` FROM `ps_stock_available` WHERE `id_product` = $id");
            $output = "";

            if($sql_q)
            {
                while($result = mysqli_fetch_assoc($sql_q))
                {
                    $output[] = $result;
                    //echo $result['id_product'] . "<br>";
                }

                if($output)
                {
                    //echo 'qty: ' . $output[0]['quantity'] . "<br>";
                    //echo 'phys qty: ' . $output[0]['physical_quantity'] . "<br>";
                    //echo 'res qty: ' . $output[0]['reserved_quantity'] . "<br>";
                }
                else
                {
                    echo "empty ressult set <br>";
                }
            }
            else
            {
                echo 'Invalid query: ' . mysqli_error() . "<br>";
            }

            return $output[0];
        }
        catch (Exception $ex) {
            // Shows a message related to the error
            echo 'Error: <br />' . $ex->getMessage();
        }
    }

    public function getPriceAndStockFromVendus ($id)
    {
        try
        {
            $url     = 'https://www.vendus.pt/ws/v1.1/products/';
            $apiKey  = '***********';
            $method  = 'GET';

            $params  = array(
                'reference'         => $id, 
            );

            $url .= '?' . http_build_query($params);
            $curl = curl_init($url);

            curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
            curl_setopt($curl, CURLOPT_USERPWD, $apiKey);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);

            //echo 'URL to Vendus - ' . $url . '<br />';

            $result = curl_exec($curl);

            $resultArray = json_decode($result, true);

            curl_close($curl);

            return array($resultArray[0]['gross_price'], $resultArray[0]['stock']);
        }
        catch (Exception $ex) {
            // Shows a message related to the error
            echo 'Error: <br />' . $ex->getMessage();
        }
    }

    public function updatePrice ($con, $id, $price)
    {
        try
       {
           $sql_q = mysqli_query($con,"UPDATE `ps_product` SET `price` = '$price' WHERE `id_product` = '$id'");
           $sql_q = mysqli_query($con,"UPDATE `ps_product_shop` SET `price` = '$price' WHERE `id_product` = '$id' AND `id_shop` = '1'");

           if($sql_q)
           {
               //echo $sql_q;
           }
           else
           {
               echo 'Invalid query: ' . mysqli_error($con) . "\n";
           }

           echo 'Price updated (' . $id . ')' . '<br />';
       }
       catch (Exception $ex) {
            // Shows a message related to the error
            echo 'Error: <br />' . $ex->getMessage();
        }
    }

    public function updateStock ($con, $id, $stock, $resQty)
    {
        try
       {
           $newPhysQty = $stock;
           if ($newPhysQty!=0)
                $newQty = $newPhysQty - $resQty;
            else
                $newQty = 0;

           $sql_q = mysqli_query($con,"UPDATE `ps_stock_available` SET `physical_quantity` = '$newPhysQty', `quantity` = '$newQty' WHERE `id_product` = '$id'");

           if($sql_q)
           {
               //echo $sql_q;
           }
           else
           {
               echo 'Invalid query: ' . mysqli_error($con) . "\n";
           }

           echo 'Stock updated(' . $id . ')' . '<br />';
       }
       catch (Exception $ex) {
            // Shows a message related to the error
            echo 'Other error: <br />' . $ex->getMessage();
        }
    }
}
?>

计划是每隔一定时间运行此代码以保持数据库更新。

我做错什么了吗?有更快的方法吗?

此代码在具有2GB RAM且不是非常快的处理器的服务器上运行。在规格更高的计算机上是否应该毁了它?

对于代码的任何评论/批评以及如何改进的技巧,我将不胜感激。

提前谢谢! ;)

编辑:看来运行代码会产生500 Internal Server Error,您知道是什么原因引起的吗?如果我只运行一次foreach,则不会发生。我如何详细检查错误?我有CPannel作为服务器的控制面板。

0 个答案:

没有答案