2010-10-04 7 views
0

У меня есть сайт Joomla, на котором я написал пользовательский компонент корзины покупок. Пользователь в основном покупает коды, которые мы храним в нашей базе данных - они связаны с печатной рекламной картой. Когда пользователь проверяет, мне нужно захватить кусок кодов из базы данных (сколько бы они ни купили), затем прокрутить список кодов и обновить другие таблицы с информацией в моей корзине. Тележка хранится в виде массива массивов в переменной сеанса, например:Есть ли более эффективный способ запуска запросов внутри цикла? Проблемы с памятью

$cart = Array ( 
[0] => Array ([TypeFlag] => S [qty] => 25 [denom] => 50 [totalPrice] => 100) 
[1] => Array ([TypeFlag] => V [qty] => 10 [denom] => 25 [totalPrice] => 25) 
[2] => Array ([TypeFlag] => C [qty] => 100 [denom] => 25 [totalPrice] => 25) 
) 

, где каждый внутренний массив одна строка в корзине. Это проблема, вызывающая проблему; когда они низки, нет проблем с запуском всех запросов на вставку и обновление внутри цикла. Однако, когда элементы qty высоки, я начинаю получать ошибки выделения памяти. Это понятно, поскольку он в основном запускает несколько запросов сотни раз. Проблема заключается в том, что пользователь может потенциально заказать тысячу карт или больше за один раз (это корпоративная программа стимулирования), поэтому мне нужно иметь возможность вставлять и обновлять все записи независимо от того, насколько велика цифра.

Вот соответствующий код:

Во-первых, цикл:

//loop through vouchers to create purchase records, update voucher records, create certificates 
$rightNow = date("YmdHis"); 
foreach($vouchers as $voucher) { 
    $VoucherID = $voucher['VoucherID']; 
    $VoucherIDList .= $VoucherIDList ."," . $voucher['VoucherNbr']; 
    //create purchase record    
    $purchData = array("CcAuthCode"=>$ccAuthCode,"VoucherID"=>$VoucherID,"PurchAmt"=>$realFinalTotal, "ShipHandFee"=>number_format($shippingCharge,2), "PurchDT"=>$rightNow, "AcctID"=>$accountIDs['UserAcctID'], "ShipAddrID"=>$accountIDs['MailingAcctID']); 
    $purchID = $model->createPurchaseRecord($purchData);  

    //update voucher 
    $model->updateVoucherInfo($VoucherID,$accountIDs['BillingAcctID'], $denom, $purchID,$message); 
} 

Фактические запросы внутри функций createPurchaseRecord и updateVoucherInfo в модели:

function createPurchaseRecord($data){  
    $db =& JFactory::getDBO(); 
    $insFields = ""; 
    $valFields = ""; 

    foreach ($data as $f => $v){ 
     $insFields .= "," . $f; 
     $valFields .= "," . $db->quote($v); 
    } 

    $insFields = substr($insFields,1); 
    $valFields = substr($valFields,1); 

    $query = "insert into arrc_PurchaseActivity ({$insFields}) values ({$valFields})"; 
    $db->setQuery($query); 
    if (!$db->query()) error_log($db->stderr()); 

    return $db->insertid(); 
} 

function updateVoucherInfo($voucherID,$billingAcctId, $balanceInit, $purchID, $certMessage) { 
    //set ActivatedDT, BalanceInit 
    $rightNow = date("YmdHis"); 
    $db =& JFactory::getDBO(); 
    $query = "UPDATE arrc_Voucher 
     set ActivatedDT=".$db->quote($rightNow).", BalanceInit=".$db->quote($balanceInit) . ", BalanceCurrent=".$db->quote($balanceInit). 
    ", AcctID=".$db->quote($billingAcctId).", PurchActvtyID=".$db->quote($purchID) . ", certMessage=".$db->quote($certMessage) 
    . " WHERE VoucherID=".$db->quote($voucherID); 

    $db->setQuery($query); 
    if (!$db->query()) error_log($db->stderr()); 
    $certificateNumber = $voucherID; 
    return $certificateNumber; 

}

Может ли кто-нибудь помочь мне? Должен быть способ сделать это более эффективным; прямо сейчас он бросает ошибку памяти, когда я пытаюсь сделать больше 30 или около того одновременно; учитывая требование 1000+, это большое дело. Это ошибка:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 71303153 bytes) in /var/www/html/mysite.com/components/com_arrcard/controllers/checkout.php on line 110 

линия 110 эта линия из вышеприведенного цикла:

$VoucherIDList .= $VoucherIDList ."," . $voucher['VoucherNbr']; 

ответ

3
$VoucherIDList .= $VoucherIDList ."," . $voucher['VoucherNbr']; 

Вы делаете это неправильно. Вы объединяете этот список, приводя к тому, что переменная растет экспоненциально.

Правильный путь:.

$VoucherIDList .= "," . $voucher['VoucherNbr']; 

или

$VoucherIDList = $VoucherIDList ."," . $voucher['VoucherNbr']; 

С уважением, Алинь

+0

Спасибо! Я изменяю код, написанный кем-то другим, и поскольку он всегда работал в прошлом, я не слишком внимательно смотрел на него и пропустил это. – EmmyS

-1

$VoucherIDList .= $VoucherIDList ."," . $voucher['VoucherNbr'];

С = оператор вы делаете конкатенации $VoucherIDList к себе.

С вышеуказанным утверждением вы также можете добавить $VoucherIDList в список еще раз.

Как сказано выше, вы добавляете переменную к себе экспоненциально каждый раз, когда цикл работает.

Я думаю, именно поэтому вы получаете проблемы с ошибкой.

+0

это то, что @Alin Purcary сказал перед вами ... Вид бесполезно – Alex

1

Чтобы сделать ваш код чище и устранить ненужные звонки.

Вместо

foreach ($data as $f => $v){ 
    $insFields .= "," . $f; 
    $valFields .= "," . $db->quote($v); 
} 

Использование

$valFields = implode(',', $data); 
$insFields = implode(',', array_keys($data)); 

использование Увеличение памяти в php.ini

Если вы используете PHP 5, свободно &.

Вместо того, чтобы перебирать массив массивов. Загрузите $vouchers в виде массива объектов, объекты передаются по ссылке вместо значения.

foreach($vouchers as $voucher) { 
+0

Невозможно увеличить использование памяти; это хостинг-сайт, и у меня нет контроля над этим (хост тоже не изменит его.) Что касается загрузки $ ваучеров как массива объектов, а не массива массивов: я новичок в OO PHP; Я не уверен, что вы подразумеваете под этим или как это сделать. Вы можете уточнить? – EmmyS

+0

В вашем случае может быть лучше создать объект таблицы, посмотрите документы Joomla - http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_6_-_Adding_Backend_Actions. Переход на OO окажется довольно уродливым, особенно если все ваше приложение основано на массивах. – Alex

 Смежные вопросы

  • Нет связанных вопросов^_^