Domanda

Ho un sito web Joomla che ho scritto un componente carrello della spesa personalizzato per. L'utente è fondamentalmente acquista codici stiamo memorizzazione nel nostro database - questi sono associati con una carta di incentivazione stampata. Quando l'utente estrae, ho bisogno di afferrare un pezzo di codici dal database (comunque molti che hanno acquistato), quindi scorrere l'elenco dei codici e aggiornare altre tabelle con le informazioni in mio carrello. Il carrello viene memorizzata come una matrice di matrici in una variabile di sessione, in questo modo:

$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 ) 
) 

dove ogni matrice interna è un elemento pubblicitario nel carrello. E 'il qty che sta causando il problema; Quando sono a basso non c'è alcun problema in esecuzione tutte le query di inserimento e aggiornamento all'interno del ciclo. Tuttavia, quando gli elementi qty sono alti, comincio a ricevere errori di allocazione di memoria. Questo è comprensibile, in quanto è fondamentalmente in esecuzione diverse query centinaia di volte. Il problema è, un utente potrebbe potenzialmente ordinare un migliaio di carte o più alla volta (si tratta di un programma di incentivazione aziendale), quindi ho bisogno di essere in grado di ottenere tutti i record inseriti e aggiornati, indipendentemente da quanto grande il qty è.

Ecco il codice in questione:

In primo luogo, il ciclo:

//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);
}

Le query reali sono all'interno delle funzioni createPurchaseRecord e updateVoucherInfo nel modello:

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;

}

Qualcuno può darmi una mano? Ci deve essere un modo per renderlo più efficiente; In questo momento è gettando un errore di memoria quando cerco di fare di più di 30 o giù di lì in un momento; data l'esigenza di 1.000 +, questo è un grosso problema. Questo è l'errore:

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

Linea 110 è questa linea dal ciclo precedente:

   $VoucherIDList .= $VoucherIDList ."," . $voucher['VoucherNbr'];
È stato utile?

Soluzione

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

Si sta facendo questo torto. È concatenare la lista a se stesso con conseguente variabile crescita esponenziale.

maniera corretta:

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

o

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

Saluti, Alin

Altri suggerimenti

Per rendere il vostro po 'più pulito il codice ed eliminare le chiamate inutili.

Al posto di

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

Usa

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

Utilizzo Aumentare la memoria in php.ini

Se si utilizza PHP 5, & sciolto.

Invece di collegamento in cascata array di array. Carico $vouchers come array di oggetti, oggetti vengono passati per riferimento invece del valore.

foreach($vouchers as $voucher) {

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

Con la. = Operatore si sta facendo una concatenazione di $VoucherIDList a se stesso.

Con la dichiarazione di cui sopra, si aggiunge poi anche $VoucherIDList alla lista di nuovo.

Come Alin detto sopra, si aggiunge la variabile a se stessa in modo esponenziale ogni volta che viene eseguito il ciclo.

Direi questo è il motivo per cui si stanno ottenendo i problemi di errore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top