I did some research about division by zero error in PHP. I found a couple of most of them said to do an if statement like I did with my code below, but I am still getting an error, can someone tell me what's wrong with my code?
<?php
$result = array(
'price' => 0,
'special' => 80
);
$product = array(
'savings' => round((($result['price'] - $result['special'])/$result['price'])*100, 0)
);
if ($result['price'] == 0) {
echo $result['price'];
} else {
echo "You will save " . $product['savings'] ."%";
}
?>
I tried both
If == 0 and if != 0
as I am fairly new to PHP, won't my if statement mean if the price of product = 0 than echo out the price and if it's not than echo out the special price?
I'm not allowed to move the $product array.
This seems to make more sense, money-wise: check first if the price is higher than the special, and if so, perform the calculation.
$product = array(
'savings' => ($result['price'] > $result['special'] ? (round((($result['price'] - $result['special'])/$result['price'])*100, 0)) : 0)
);
You have to move the division inside your if/else statement.
$result = array(
'price' => 100,
'special' => 80
);
if ($result['price'] == 0) {
echo $result['price'];
} else {
$product = array('savings' => round((($result['price'] - result['special'])/$result['price'])*100, 0)
);
echo "You will save " . $product['savings'] ."%";
}
Related
I'd like to check if array exist by two keys: id and type
This code just check by id:
if (isset($_POST['type'])) {
$type = $_POST['type'];
}
else {
$type = '';
}
if (array_key_exists($id, $_SESSION['cart'])) {
$_SESSION['cart'][$id]['quantity'] += $quantity;
} else {
$_SESSION['cart'][$id] = $line;
}
I have tried with this code but it doesn't work:
if (array_key_exists($id, $_SESSION['cart']) && array_key_exists($type, $_SESSION['cart'])) {
$_SESSION['cart'][$id]['quantity'] += $quantity;
} else {
$_SESSION['cart'][$id] = $line;
}
$_SESSION['cart'] is an array contains arrays of $line
$line = array(
'id' => $id,
'type' => $type,
'quantity' => $quantity,
'price' => $price,
'picture' => $dish->getPicture()->getWebPath(),
);
This is the output of $_SESSION['cart']:
As you see in th last array with id 55 and type "french bred" , what I'd like to do is to check if th user chose the same product but a with different type so insert new line else if the same product and the same type so just update quantity.
Something like this should do, however the question is too vague and too little code is shown for me to properly understand your problem
$lineExists = false;
foreach($_SESSION['cart'] as $index => $line){
if($line['id'] === $id)
{
$_SESSION['cart'][$index]['quantity'] += $quantity;
$lineExists = true;
}
}
if(!$lineExists)
{
$_SESSION['cart'][] = $newLine;
}
If you want to check if type and id exists then you should do something like this
if (array_key_exists('id', $_SESSION['cart']) && array_key_exists('type', $_SESSION['cart'])) {
// stuff here..
}
if $id is the value of the key id so 'id' => 5 then you should check like this:
if ($_SESSION['cart']['type'] == $id) {
// stuff here
}
Hope this somewhat helps you further!
I've inherited a project written in PHP which has a double entry style cashbook, which requires that the amount going in is equal to the amount going out.
When validating figures entered via a form (to work out if it equals zero), it runs the code below which works fine until there is a decimal number, which seems to make it randomly fall over and return an incorrect value.
In the example below, it returns a really tiny number from 53.87 - 53.87, which should be zero.This has been stripped back to eliminate other things from causing problems, so I've removed a lot of input validation etc.
<?php $inputs = array(
array(
"in" => '',
"out" => '249.6',
),
array(
"in" => '',
"out" => '396',
),
array(
"in" => '554.4',
"out" => ''
),
array(
"in" => '145.07',
"out" => ''
),
array(
"in" => '',
"out" => '53.87',
),
);
$fTotal = 0;
echo "Start at 0: ";
foreach($inputs as $key=>$sRef) {
$itemValid = true;
$aItem = array();
$amountIn = $inputs[$key]['in'];
$amountOut = $inputs[$key]['out'];
if ($itemValid) {
echo "'".$fTotal."'";
$is_in = 0;
if ($amountIn > 0.0) {
$is_in = 1;
echo "+";
$amount = $amountIn;
$fTotal = $fTotal + $amountIn;
} else {
$is_in = 0;
echo "-";
$amount = $amountOut;
$fTotal = $fTotal - $amountOut;
}
echo "'".$amount."'=";
echo "'".$fTotal."' | ";
$aItem["is_in"] = $is_in;
$aItem["amount"] = $amount;
$aItems[] = $aItem;
}
}
You can run this on a sandbox here.
Here is the expected output:
Start at 0: '0'-'249.6'='-249.6' | '-249.6'-'396'='-645.6' | '-645.6'+'554.4'='-91.2' | '-91.2'+'145.07'='53.87' | '53.87'-'53.87'='0' |
Here is the actual output:
Start at 0: '0'-'249.6'='-249.6' | '-249.6'-'396'='-645.6' | '-645.6'+'554.4'='-91.2' | '-91.2'+'145.07'='53.87' | '53.87'-'53.87'='-4.9737991503207E-14' |
What is wrong here?
Update
Following help below, here's the working code for anyone who stumbles on this in the future.
This is happening because of floating point (decimal) maths where computers like binary maths. Sometimes decimal numbers don't have a nice representation in binary so these tiny differences happen.
If you can state that every number can be rounded to 2 decimal points, and based on your limited dataset, wrapping your 'sums' in number_format($fTotal + $amountIn , 2) etc can sort this out for you.
Alternatively for a "more accurate", just wrap the final one eg. echo "'".number_format($fTotal, 2)."' | "; (or 0 or whatever)
Your numbers are being interpreted as strings.
Try this:
<?php
$inputs = array(
array(
"in" => 0,
"out" => 249.6,
),
array(
"in" => 0,
"out" => 396,
),
array(
"in" => 554.4,
"out" => 0
),
array(
"in" => 145.07,
"out" => 0
),
array(
"in" => 0,
"out" => 53.87,
),
);
$fTotal = 0;
echo "Start at 0: ";
foreach($inputs as $key => $sRef) {
$itemValid = true;
$amountIn = $sRef['in'];
$amountOut = $sRef['out'];
if ($itemValid) {
echo $fTotal;
$is_in = 0;
if ($amountIn > 0.0) {
$is_in = 1;
echo "+";
$amount = floatval($amountIn);
$fTotal = floatval($fTotal) + floatval($amountIn);
} else {
$is_in = 0;
echo "-";
$amount = floatval($amountOut);
$fTotal = floatval($fTotal) - floatval($amountIn);
}
echo $amount;
echo ' = ' . $fTotal . " | ";
}
}
The bcsub() function in PHP is an inbuilt function and is used to subtract one arbitrary precision number from another.
Syntax:
string bcsub ( $num_str1, $num_str2, $scaleVal)
Example :
<?php $num_str1 = "8"; $num_str2 = "3"; $res = bcsub($num_str1, $num_str2) echo $res; ?>
Result:
5
I've created php ekart site just for testing purpose. My query is when I click on add to cart it should firstly validate whether any one color and any one size is selected, if both have been selected it adds product to the cart this works fine but if I add same product but with different color or size it overlaps the same product which was already added and that products quantity turns to 1 but if I select another product it works well but same thing goes when I select different size or color. Since I am a beginner at php, I'm not sure where am I going wrong here.
Php code of Product add to cart is given Below:
$sql = "SELECT * FROM allprods WHERE listing = '$listing' and id = '$id'";
$data = mysql_query($sql);
if (mysql_num_rows($data) == 1)
{
$row = mysql_fetch_array($data);
if (isset($_SESSION['cart'][$id]))
{
if(isset($_SESSION['cart'][$id][$color]) && isset($_SESSION['cart'][$id][$size]))
{
$_SESSION['cart'][$id]['quantity']++;
echo "<script>alert('".$row['product_name']." has been added to your cart.');</script>";
}
else
{
$_SESSION['cart'][$id] = array('quantity' = >1, 'price' => $row['product_special_price'], 'cat' => $cat, 'id' => $id, 'size' => $size, 'color' => $color, 'name' => $row['product_name']);
echo "<script>alert('" . $row['product_name'] . " has been added to your cart.');</script>";
}
}
else
{
$_SESSION['cart'][$id] = array('quantity' => 1, 'price' => $row['product_special_price'], 'cat' => $cat, 'id' => $id, 'size' => $size, 'color' => $color, 'name' => $row['product_name']);
echo "<script>alert('" . $row['product_name'] . " has been added to your cart.');</script>";
}
}
Cart program code
<?php
if(isset($_POST['qty']))
{
foreach($_POST['qty'] as $product_id=>$item_qty)
{
$id=(int)$product_id;
$qty=(int)$item_qty;
if($qty==0)
{
unset($_SESSION['cart'][$id]);
}
elseif($qty>0)
{
$_SESSION['cart'][$id]['quantity']=$qty;
}
}
}
else
{
echo "";
}
if(!empty($_SESSION['cart']))
{
require "../link_db.php";
$sql="SELECT * FROM allprods WHERE id IN(";
foreach($_SESSION['cart'] as $id=>$value)
{
$sql.=$id.',';
}
$sql=substr($sql,0,-1).') ORDER BY product_id ASC';
$data=mysql_query($sql);
while($row=mysql_fetch_array($data))
{
?>
Table row and data goes here!!
<?php
}
else
{
?>
<tr>
<th colspan='4' class='noprodavailablewrap'>
There are no products in your cart.
</th>
</tr>
<?php
}
?>
DB structure given below:
Use this code
<?php
$sql = "SELECT * FROM allprods WHERE listing = '$listing' and id = '$id'";
$data = mysql_query($sql);
if (mysql_num_rows($data) == 1)
{
$row = mysql_fetch_array($data);
$index = md5($id.$color.$size);
if( isset($_SESSION['cart'][$index]) && isset($_SESSION['cart'][$index]['color']) && $_SESSION['cart'][$index]['color'] == $color && isset($_SESSION['cart'][$index]['size']) && $_SESSION['cart'][$index]['size'] == $size){
$_SESSION['cart'][$index]['quantity']++;
echo "<script>alert('".$row['product_name']." has been added to your cart.');</script>";
}else{
$_SESSION['cart'][$index] = array('quantity' => 1, 'price' => $row['product_special_price'], 'cat' => $cat, 'id' => $id, 'size' => $size, 'color' => $color, 'name' => $row['product_name']);
echo "<script>alert('" . $row['product_name'] . " has been added to your cart.');</script>";
}
}
?>
I'm working with an existing foreach that is stepping through an array of values pulled from the database. I'd like to perform some logic based on each key/value pair and assign some values to variables to output as part of the foreach loop.
Specifically I need to output the availability as determined based on some values for each key/pair. My logic works, but the value of the last record is assigned to EVERY record that passes the conditional tests, even if the values are different.
How can I assign $value['availability'] correctly for each time through the loop?
Here's my code:
foreach ($prices as $value) {
if(!$this->_validateAttributeValue($attributeId, $value, $options)) {
continue;
}
$currentProduct->setConfigurablePrice(
$this->_preparePrice($value['pricing_value'], $value['is_percent'])
);
$currentProduct->setParentId(true);
Mage::dispatchEvent(
'catalog_product_type_configurable_price',
array('product' => $currentProduct)
);
$configurablePrice = $currentProduct->getConfigurablePrice();
if (isset($options[$attributeId][$value['value_index']])) {
$productsIndex = $options[$attributeId][$value['value_index']];
} else {
$productsIndex = array();
}
/* Check the quantity */
if($options['qty'][$value['label']] <= 0) {
if ($product->getResource()->getAttribute('item_status')->getFrontend()->getValue($product) == "Preorder") { // Preorder
$value['availability'] = "Pre-order";
}
elseif ($product->getResource()->getAttribute('item_status')->getFrontend()->getValue($product) != "Discontinued") { // Must be an active backorder item
if ($product->getResource()->getAttribute('new_availability')->getFrontend()->getValue($product) != "No") {
$value['availability'] = $product->getResource()->getAttribute('new_availability')->getFrontend()->getValue($product);
}
else {
$value['availability'] = "Temporarily out of stock";
}
}
}
$info['options'][] = array(
'id' => $value['value_index'],
'label' => ($options['qty'][$value['label']] <= 0) ? $value['label'] . ': '.$value['availability'].'' : $value['label'] . ": In stock",
'price' => $configurablePrice,
'oldPrice' => $this->_prepareOldPrice($value['pricing_value'], $value['is_percent']),
'products' => $productsIndex,
);
$optionPrices[] = $configurablePrice;
}
Try
foreach ($prices as $key=>$value){
//your code
}
I have a product import code for Magento that assigns inventory (qty) to a warehouse location (stock_id). The information is passed in an array however my working knowledge of arrays isn't that flash so I'm sure I'm not doing this correctly.
The import is currently done like this however I'm sure it's not the most efficient as I'm saving the product twice.
This will assign a qty of 100 to location 1 (stock_id 1), save the product, then assign a qty of 200 to location 2 (stock_id 2) and then save the product again.
$stocksData = $product->getStocksData();
if (!$stockData) {
$stockData = array();
}
$stockData['stock_id'] = 1;
$stockData['qty'] = 100;
$stocksData[$stockId] = $stockData;
$product->setStocksData($stocksData);
$product->setCreatedAt(strtotime('now'));
try {
$product->save();
echo "Successful";
}
catch (Exception $ex) {
echo 'There was an error :<br/>' .$ex;
}
$stocksData = $product->getStocksData();
if (!$stockData) {
$stockData = array();
}
$stockData['stock_id'] = 2;
$stockData['qty'] = 200;
$stocksData[$stockId] = $stockData;
$product->setStocksData($stocksData);
$product->setCreatedAt(strtotime('now'));
try {
$product->save();
echo "Successful";
}
catch (Exception $ex) {
echo 'There was an error :<br/>' .$ex;
}
What I'm trying to achieve is to set all of the values in the array and save once as this will take a lot of load off the script.
I've been playing around with stuff like this, however haven't got anywhere and usually end up with errors:
$stocksData = $product->getStocksData();
if (!$stockData) {
$stockData = array();
}
$stockData = array(
[$stockData['stock_id'] = 1] => $stockData['qty'] = 100,
[$stockData['stock_id'] = 2] => $stockData['qty'] = 200
);
$stocksData[$stockId] = $stockData;
$product->setStocksData($stocksData);
I'm assuming it's possible to have all of this information in one array but I'm just not sure how.
There are a lot of ways to initialize an array in php.
$stocksData = array(
'key' => 'value',
'myarr' => array(
'nested' => 'array',
1,
),
'id_copy' => $stocksData['id'],
'qty' => $stocksData['stock_id'] == 1 ? 100 : 200,
);
For a full explanation of array syntax, check out php's Array documentation. Also note my usage of the ternary operator. You can get around using this syntax by saying something like:
if ($stocksData['id'] == 1) {
$stocksData['qty'] = 100;
}
else {
$stocksData['qty'] = 200;
}
Edit:
For your specific use case of combining the requests, take a look below:
$stocksData = $product->getStocksData();
$stocksData[1] = array(
'stock_id' => 1,
'qty' => 100,
);
$stocksData[2] = array(
'stock_id' => 2,
'qty' => 200,
);
$product->setStocksData($stocksData);