カスタムショッピングカートコンポーネントを作成したJoomlaWebサイトがあります。ユーザーは基本的に、データベースに保存しているコードを購入しています。これらは、印刷されたインセンティブカードに関連付けられています。ユーザーがチェックアウトするとき、データベースからコードのチャンクを取得し(購入したコードの数に関係なく)、コードのリストをループして、カート内の情報で他のテーブルを更新する必要があります。カートは、次のように、配列の配列としてセッション変数に格納されます。
$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 )
)
ここで、各内部配列はカート内の1つのラインアイテムです。問題を引き起こしているのは数量です。それらが低い場合、ループ内ですべての挿入および更新クエリを実行しても問題はありません。ただし、qty要素が多いと、メモリ割り当てエラーが発生し始めます。基本的に数百回のクエリを実行しているため、これは理解できます。問題は、ユーザーが一度に1,000枚以上のカードを注文する可能性があるため(これは企業のインセンティブプログラムです)、数量に関係なく、すべてのレコードを挿入して更新できるようにする必要があります。
関連するコードは次のとおりです。
まず、ループ:
//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程度を超えて実行しようとすると、メモリエラーがスローされます。1,000以上の要件を考えると、これは大きな問題です。これはエラーです:
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'];