我正在研究一个项目,该项目根据自动售货程序中的数据更新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作为服务器的控制面板。