好的,所以我有一个篮子,它有一个$ iEmployeeNumbers变量,默认情况下设置为10.
构建时,将其写入23。
当在insert语句之前死亡时,变量为23,而在insert语句之后死亡时变量为23。
如果我在insert语句之后死亡,那么数据库中的值是正确的,但是如果我让函数运行直到它返回到返回主代码,则存储在数据库中的值将设置为10。
class basket
{
// Basket ID
private $id = 0;
// Session ID
private $sessionId = null;
// client id
private $iClientId = 0;
// array with the index of the deck product and the value of array('product', 'status')
private $aryItems = array();
// array of deck products
private $aryCurrentSubscrition = array();
// employee numbers
private $iEmployeeNumbers = 10;
/**
* Set up the basket with the current subscribed decks passed in
* @param $iCurrentEmployeeNumbers An int of the current employee numbers from the system
* @param $aryCurrentDeckProducts An array of currently subscribed to deck products
*/
function __construct($api, $sessionId, $iCurrentEmployeeNumbers, $aryCurrentDecks = null)
{
$this->sessionId = $sessionId;
$this->setEmployeeNumbers($iCurrentEmployeeNumbers);
//die('shizzle:'.$this->iEmployeeNumbers);
// check if $aryCurrentDeckProducts is not null
if ($aryCurrentDecks !== null)
{
// loop through deck products adding them to the arrays
foreach ($aryCurrentDecks as $objDeck)
{
// set the current subscribed decks to the ones passed in the construct.
$this->aryCurrentSubscription[$objDeck->id] = $objDeck;
}
}
}
/**
* Add an item to the basket
* @param $objDeck The deck to add.
* @param $sStatus The status of the item ('added', 'changed', 'removed', 'existing')
*/
public function addItem($objDeck)
{
// check if the deck product exists in the basket already
if (!empty($this->aryItems) && array_key_exists($objDeck->id, $this->aryItems))
{
// check if the deck product was part of the existing subscription
if (!empty($this->aryCurrentSubscription) && array_key_exists($objDeck->id, $this->aryCurrentSubscription) && $this->aryCurrentSubscription[$objDeck->id]['deck']->compare($objDeck))
{
// the product was in the basket at the start of the shop and has been re-added
// so set it to existing and avoid double charging them for the initial setup
$this->aryItems[$objDeck->id]['status'] = 'existing';
}
else
{
if ($this->aryItems[$objDeck->id]['product']->compare($objDeck))
{
// the product was added then removed from the basket but was not
// in the current subscription so set its status back to added
$this->aryItems[$objDeck->id]['status'] = 'added';
}
else
{
// the product was added but does exist in the basket as a different
// set of addons
$this->aryItems[$objDeck->id]['status'] = 'changed';
}
}
}
else
{
// the product is not in the cart so add it as a new one
$this->aryItems[$objDeck->id] = array('product' => $objDeck, 'status' => 'added');
}
}
/**
* Remove an item from the basket
* @param $objDeckProduct The deck product to remove
* @return bool true|false
*/
public function removeItem($objDeck)
{
// Check if the product is in the basket
if (array_key_exists($objDeck->id, $this->aryItems))
{
// Set the status of the product to removed
$this->aryItems[$objDeck->id]['status'] = 'removed';
return true;
}
// the item does not exist in the basket
return false;
}
/**
* Get the totals from the basket
* @return array ('setup', 'monthly', 'equivalent', 'setup_formatted', 'monthly_formatted', 'equivalent_formatted')
*/
public function getTotals()
{
// set up a running total for adding up all the costs involved
$runningTotal = array('setup' => 0, 'monthly' => 0, 'equivalent' => 0);
// loop through all items and process them based on status
foreach ($this->aryItems as $aryItem)
{
// only process items that are NOT removed
if ($aryItem['status'] !== 'removed')
{
// get the calcualate the deck prices
$deckPrices = $this->calculatePrices($aryItem['product']);
// because the setup check is done at addon level inside the get deck prices
// we can just add the setup cost
$runningTotal['setup'] += $deckPrices['setup'];
$runningTotal['monthly'] += $deckPrices['monthly'];
$runningTotal['equivalent'] += $deckPrices['equivalent'];
}
}
// format all the numbers
$runningTotal['setup_formatted'] = $this->stringNumberFormat(bcdiv($runningTotal["setup"], 100, 2));
$runningTotal['monthly_formatted'] = $this->stringNumberFormat(bcdiv($runningTotal["monthly"], 100, 2));
$runningTotal['equivalent_formatted'] = $this->stringNumberFormat(bcdiv($runningTotal["equivalent"], 100, 2));
return $runningTotal;
}
/**
* Calculate the prices for any given deck
* @param $objDeck The deck to process
* @param $iEmployees The number of employees to calculate against
* @return array ('setup', 'monthly', 'equivalent', 'setup_formatted', 'monthly_formatted', 'equivalent_formatted')
*/
function calculatePrices($objDeck, $iEmployees = null)
{
if ($iEmployees === null)
{
$iEmployees = $this->iEmployeeNumbers;
}
$prices = array();
// calculate the monthly total with the support cost
// FIXME need to implement discount for the deck price
$iMonthlyPrice = $objDeck->price * $iEmployees;
$iSetupPrice = 0;
$deckIsInBasket = false;
if (!empty($this->aryCurrentItems) && array_key_exists($objDeck->id, $this->aryCurrentItems))
{
$deckIsInBasket = true;
}
foreach ($objDeck->addons as $addon)
{
// if the deck is in the current subscription do the other two checks else skip to adding the setup cost
if (($deckIsInBasket && (empty($this->aryCurrentItems[$objDeck->id]->addons) || !array_key_exists($addon->id, $this->aryCurrentItems[$objDeck->id]->addons))) || !$deckIsInBasket)
{
$iSetupPrice += $addon->setup_price;
}
$iMonthlyPrice += $addon->price * $iEmployees;
}
// set up the returned array
$prices["setup"] = $iSetupPrice;
$prices["monthly"] = $iMonthlyPrice;
$prices["equivalent"] = (int) round($iMonthlyPrice / $iEmployees, 0);
$prices["setup_formatted"] = $this->stringNumberFormat(bcdiv($prices["setup"], 100, 2));
$prices["monthly_formatted"] = $this->stringNumberFormat(bcdiv($prices["monthly"], 100, 2));
$prices["equivalent_formatted"] = $this->stringNumberFormat(bcdiv($prices["equivalent"], 100, 2));
return $prices;
}
/**
* Format a string number to currency format
* @param $sNumber The number to be formatted as currency
* @return string The formatted number
*/
function stringNumberFormat($sNumber)
{
// check for any existing decimal places
$parts = explode(".", $sNumber);
// if there was no decimal place set the pennies to 00
if (count($parts) === 1)
{
$parts[1] = "00";
}
// if the number has less then 3 digits e.g. less than 1000 then return
// the formatted parts with a decimal place
if (strlen($parts[0]) <= 3)
{
return implode(".", $parts);;
}
// prepare the formatted string
$formattedString = $parts[0];
// set the added characters to empty
$added = "";
// set the thousands to an empty array
$thousands = array();
// calculate the remainder of dividing the string length by 3
// this tells us how many 0's to add at the start of the string
// we add the 0's to make it easy to step through every thousand
$remainder = (int) bcmod(strlen($formattedString), 3);
// if the remainder is 1 add two 0's (e.g. 1000 now looks like 001000)
if ($remainder === 1)
{
$added = "00";
}
// if the remainder is 2 add one 0 (e.g. 10000 now looks like 010000)
elseif ($remainder === 2)
{
$added = "0";
}
// if it divided by three with no remainder then there is no need to add any
// add the prefix to the start
$formattedString = $added . $formattedString;
// for the length of the string step through every 3 characters
for ($x = 3; $x <= strlen($formattedString); $x += 3)
{
// minus this many off the start of the string
$minus = 0;
// for the first step only
if ($x === 3)
{
// set minus to the number of 0's added
$minus = strlen($added);
}
// set each set of thousands to a new part
$thousands[] = substr($formattedString, $x - 3 + $minus, 3 - $minus);
}
// put all the groups of 3 characters back together with the
// seperator of ,
$parts[0] = implode(",", $thousands);
// add the decimal places back on and return
return implode(".", $parts);
}
/**
* Get the number of employees
* @return int Number of employees
*/
public function getEmployeeNumbers()
{
return $this->iEmployeeNumbers;
}
/**
* Sets the number of employees
* @param $iNewEmployeeNumbers
* @return bool successful
*/
public function setEmployeeNumbers($iNewEmployeeNumbers)
{
if (is_numeric($iNewEmployeeNumbers) && (int) $iNewEmployeeNumbers >= 10)
{
echo 'iem:'.$this->iEmployeeNumbers.' inew:'.$iNewEmployeeNumbers;
$this->iEmployeeNumbers = (int) $iNewEmployeeNumbers;
echo 'iemnew:'.$this->iEmployeeNumbers;
//die('in this if');
return true;
}
else
{
return false;
}
}
/**
* Get the client id
* @return int client id
*/
public function getClientId()
{
return $this->iClientId;
}
/**
* Sets the client id, can only be called if client id is not already set
* @param $iNewClientId
* @return bool successful
*/
public function setClientId($iNewClientId)
{
if (is_numeric($iNewClientId) && (int) $iNewClientId > 0 && $this->iClientId == 0)
{
$this->iClientId = (int) $iNewClientId;
return true;
}
else
{
return false;
}
}
/**
* Gets an array of items for displaying on the basket page.
* @return array of deck products.
*/
public function getDecks()
{
$activeItems = array();
foreach($this->aryItems as $aryItem)
{
// only process items that are added
if ($aryItem['status'] !== 'removed')
{
$activeItems[$aryItem['product']->id] = $aryItem['product'];
}
}
return $activeItems;
}
/**
* Sets the aryItems
* @params array $aryDecks an array of decks to be set
*/
public function setDecks($aryItems)
{
foreach($aryItems as $objDeck)
{
$this->addItem($objDeck);
}
}
/**
* Gets 'true' or 'false' if the client had decks at the start of the process
* @return string 'true' or 'false'
*/
public function hasDecks()
{
if (count($this->aryCurrentSubscription) > 0)
{
return 'true';
}
else
{
return 'false';
}
}
/**
* Builds the billing agreement description
* @return string The billing agreement description
*/
public function getBillingAgreementDescription($sResellerName)
{
$description = "Your subscription with " . $sResellerName . ".";
return $description;
}
/**
* FIXME Add a function for calculating revenue splits and amounts.
*
*/
/**
* Saves the added items to the database for checkout resumption
* @return bool successful?
*/
public function save()
{
$db = database::getDBO();
$id = $this->basketExists();
if (!$id)
{
$db->beginTransaction();
$query = $db->prepare("INSERT INTO `baskets` (`session_id`, `employee_numbers`) VALUES (?, ?)");
$query->bindParam(1, $this->sessionId, PDO::PARAM_STR);
$query->bindValue(2, $this->iEmployeeNumbers, PDO::PARAM_INT);
$query->execute();
$this->id = $db->lastInsertId();
if ($this->id != 0)
{
$query = $db->prepare("INSERT INTO `basket_items` (`basket_id`, `deck_addon_id`, `status`) VALUES (?, ?, ?)");
$query->bindParam(1, $this->id, PDO::PARAM_INT);
foreach ($this->aryItems as $aryItem)
{
foreach ($aryItem['product']->addons as $addon)
{
$query->bindParam(2, $addon->id, PDO::PARAM_INT);
$query->bindParam(3, $aryItem['status'], PDO::PARAM_STR);
if (!$query->execute())
{
$db->rollBack();
return false;
}
}
}
return $db->commit();
}
else
{
$db->rollBack();
return false;
}
}
else
{
$this->id = $id;
// $db->beginTransaction();
$iEmps = $this->iEmployeeNumbers;
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// $this->iEmployeeNumbers = $this->iEmployeeNumbers + 1;
$query = $db->prepare("UPDATE `baskets` SET `session_id` = ?, `employee_numbers` = ? WHERE `id` = ?");
$query->bindParam(1, $this->sessionId, PDO::PARAM_STR);
//die(print_r($this->iEmployeeNumbers,1));
$query->bindValue(2, $this->iEmployeeNumbers, PDO::PARAM_INT);
$query->bindParam(3, $this->id, PDO::PARAM_INT);
$query->execute();
/*foreach ($this->aryItems as $aryItem)
{
foreach ($aryItem['product']->addons as $addon)
{
$iBasketItemId = $this->basketItemExists($addon->id);
if ($iBasketItemId > 0)
{
$query = $db->prepare("UPDATE `basket_items` SET `basket_id` = ?, `deck_addon_id` = ?, `status` = ? WHERE `id` = ?");
$query->bindParam(4, $iBasketItemId, PDO::PARAM_INT);
}
else
{
$query = $db->prepare("INSERT INTO `basket_items` (`basket_id`, `deck_addon_id`, `status`) VALUES (?, ?, ?)");
}
$query->bindParam(1, $this->id, PDO::PARAM_INT);
$query->bindParam(2, $addon->id, PDO::PARAM_INT);
$query->bindParam(3, $aryItem['status'], PDO::PARAM_STR);
if (!$query->execute())
{
$db->rollBack();
return false;
}
}
}*/
return true;
// return $db->commit();
// die('shizzle2:'.$this->iEmployeeNumbers);
}
}
/**
* Loads a basket from the database
* @return bool sucess
*/
public function load($api)
{
if ($this->basketExists())
{
$db = database::getDBO();
// Get decks & addons for invites
$query = $db->prepare("SELECT b.id, a.deck_id, bi.deck_addon_id, bi.status, b.employee_numbers FROM baskets AS b JOIN basket_items AS bi ON b.id = bi.basket_id JOIN addons AS a ON bi.deck_addon_id = a.id WHERE b.session_id = ?");
$query->bindParam(1, $this->sessionId, PDO::PARAM_STR);
$query->execute();
while ($aryRes = $query->fetch(PDO::FETCH_ASSOC))
{
// Populate basket
if (empty($this->aryitems) || !array_key_exists($aryRes['deck_id'], $this->aryItems))
{
$this->aryItems[$aryRes['deck_id']]['product'] = $api->getDeckById($iResellerId, $aryRes['deck_id']);
$this->aryItems[$aryRes['deck_id']]['status'] = $aryRes['status'];
}
$this->aryItems[$aryRes['deck_id']]['product']->addAddon($api->getDeckAddonById($aryRes['deck_addon_id']));
$this->setEmployeeNumbers($aryRes['employee_numbers']);
$this->id = $aryRes['id'];
}
return true;
}
return false;
}
/**
* function for checking if there is a basket saved against the session id
* @return mixed basket id if one exists else false
*/
public function basketExists()
{
$db = database::getDBO();
$query = $db->prepare("SELECT id FROM baskets WHERE session_id = ? ORDER BY id DESC");
$query->bindParam(1, $this->sessionId, PDO::PARAM_STR);
$query->execute();
$basket = $query->fetch(PDO::FETCH_ASSOC);
if (!empty($basket) && $basket !== false)
{
return $basket['id'];
}
return false;
}
/**
* Checks if the basket item exists
* @param int $iDeckAddonId
* @return int Basket id
*/
public function basketItemExists($iDeckAddonId)
{
$db = database::getDBO();
$query = $db->prepare("SELECT id FROM basket_items WHERE basket_id = ? AND deck_addon_id = ?");
$query->bindParam(1, $this->id, PDO::PARAM_INT);
$query->bindParam(2, $iDeckAddonId, PDO::PARAM_INT);
$query->execute();
$basket_item = $query->fetch(PDO::FETCH_ASSOC);
if (!empty($basket_item) && $basket_item !== false)
{
return $basket_item['id'];
}
return false;
}
}
构造调用看起来像这样。
$basket = new basket($api, session_id(), $aryInvite['employees']);
不久之后
$basket->save();
问题是为什么会出现这种不一致的情况?
为什么在函数内部死亡会使数据库存储23,但是如果脚本留下来返回然后死掉,则值存储为10?
感谢您的帮助。
答案 0 :(得分:0)
正在使用的框架是将页面上的图像路由回到相同的php脚本,从而使用默认设置初始化并保存篮子,而不是使用正确的设置。
/邀请/(invite_id)
页面加载并处理正确的数据。
/invites/image-title.png
导致php脚本运行而不是获取图像,因为邀请不存在导致脚本保存默认员工编号!