代码之家  ›  专栏  ›  技术社区  ›  EmmyS

是否有更有效的方法在循环内运行查询?内存问题

  •  0
  • EmmyS  · 技术社区  · 15 年前

    我有一个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元素很高时,我开始得到内存分配错误。这是可以理解的,因为它基本上运行了数百次查询。问题是,用户可能一次订购1000张或更多的卡(这是一个公司激励计划),所以我需要能够插入和更新所有记录,不管数量有多大。

    相关代码如下:

    首先,循环:

    //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 回复  |  直到 14 年前
        1
  •  3
  •   Alin P.    15 年前
    $VoucherIDList .= $VoucherIDList ."," . $voucher['VoucherNbr'];
    

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

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

        2
  •  1
  •   Alex    15 年前

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

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

    &

    $vouchers

    foreach($vouchers as $voucher) {
    
        3
  •  -1
  •   Kris.Mitchell    15 年前

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

    $VoucherIDList

    推荐文章