PDO for loop issue - php

I have a function that should calculate prices based on quantity.
The function should loop through every order and calculate every product price based on quantity, then should return order total price.
What i'm doing wrong?
public function getSumaComanda($cos) {
$suma = $this->_db->query(sprintf("SELECT (#pretredus:=`pretredus`) AS `pretredus`,(CASE #pretredus WHEN 0 THEN `prettotal` ELSE `pretredus` END) AS `prettotal` , cantitate FROM comenzi WHERE cos = '%d'", $cos));
$suma->execute();
$data_array = $suma->fetchAll(PDO::FETCH_ASSOC);
$count = $this->_db->query(sprintf("SELECT COUNT(*) FROM cosuri WHERE id='%d'", $cos));
$num = $count->fetchColumn();
for ($x = 0; $x < $num; $x++) {
$price = $data_array['cantitate'][$x] * $data_array['prettotal'][$x];
$pret = $pret + $price;
$pret = number_format($pret, 2, ".", "");
}
$rez = $pret;
return $rez . ' Lei';
}

You should learn how to basically debug your variables. With using var_dump($data_array); you can see, what's in there.
You have to use the numerical index first:
$price = $data_array[$x]['cantitate'] * $data_array[$x]['prettotal'];
Nevertheless, your second query is useless. You don't have to count the results and can use instead a while-loop:
public function getSumaComanda($cos) {
$suma = $this->_db->query(sprintf("SELECT (#pretredus:=`pretredus`) AS `pretredus`,(CASE #pretredus WHEN 0 THEN `prettotal` ELSE `pretredus` END) AS `prettotal` , cantitate FROM comenzi WHERE cos = '%d'", $cos));
$suma->execute();
while ($data_array = $suma->fetch(PDO::FETCH_ASSOC)) {
$pret += $data_array['cantitate'] * $data_array['prettotal'];
}
return number_format($pret, 2, ".", "") . ' Lei';
}

Related

Pagination for foreach loop

I currently have a method inside my "car class" that display the car:
static function getCars(){
$autos = DB::query("SELECT * FROM automoviles");
$retorno = array();
foreach($autos as $a){
$automovil = automovil::fromDB($a->marca, $a->modelo, $a->version, $a->year, $a->usuario_id, $a->kilometraje, $a->info,
$a->hits, $a->cilindrada, $a->estado, $a->color, $a->categoria, $a->precio, $a->idAutomovil);
array_push($retorno, $automovil);
}
return $retorno;
}
In my index.php I call that function
foreach(car::getCars() as $a){
That allows me to display the info this way ( of course inside the foreach I have a huge code with the details I'll display.
Is there a way to implement a pagination to that thing so I can handle 8 cars per page, instead of showing all of them at the same page?
You can add a $limit and $page parameter on your function so that it will only return a maximum of $limit number of items starting from $limit * $page(or will call it the $offset). You also need to add a function to get the total number of rows you have for automoviles table.
static function getCars($page = 0, $limit = 8){
$offset = $limit * max(0, $page - 1);
//replace this with prepared statement
$autos = DB::query("SELECT * FROM automoviles LIMIT $offset, $limit");
$retorno = array();
foreach($autos as $a){
$automovil = automovil::fromDB($a->marca, $a->modelo, $a->version, $a->year, $a->usuario_id, $a->kilometraje, $a->info,
$a->hits, $a->cilindrada, $a->estado, $a->color, $a->categoria, $a->precio, $a->idAutomovil);
array_push($retorno, $automovil);
}
return $retorno;
}
static function getTotal()
{
//query to get total number of rows in automoviles table
}
In your index.php do this:
foreach(car::getCars((isset($_GET['page']) ? $_GET['page'] : 1)) as $a){
...
}
and add the pagination links.
$total = car::getTotal();
if($total > 8) {
for($i = 1; $i <= intval(ceil(1.0 * $total / $limit)); $i++) {
echo '' . $i . ';
}
}

Rewrite a PHP function with arrays instead

Is there any way I could rewrite this function with an array instead of all these if statements? Could i maybe use some for loop together with an array? How would that look like? Any suggestions of simpler code?
Here is my php function:
function to_next_level($point) {
/*
**********************************************************************
*
* This function check how much points user has achievents and how much procent it is until next level
*
**********************************************************************
*/
$firstlevel = "3000";
$secondlevel = "7000";
$thirdlevel = "15000";
$forthlevel = "28000";
$fifthlevel = "45000";
$sixthlevel = "80000";
if($point <= $firstlevel) {
$total = ($point/$firstlevel) * 100;
$remaining = round($total);
//echo number_format($remaining, 0, '.', ' ');
return $remaining;
} elseif ($point <= $secondlevel) {
$total = ($point/$secondlevel) * 100;
$remaining = round($total);
//echo number_format($remaining, 0, '.', ' ');
return $remaining;
} elseif ($point <= $thirdlevel) {
$total = ($point/$thirdlevel) * 100;
$remaining = round($total);
//echo number_format($remaining, 0, '.', ' ');
return $remaining;
} elseif ($point <= $forthlevel) {
$total = ($point/$forthlevel) * 100;
$remaining = round($total);
//echo number_format($remaining, 0, '.', ' ');
return $remaining;
} elseif ($point <= $fifthlevel) {
$total = ($point/$fifthlevel) * 100;
$remaining = round($total);
//echo number_format($remaining, 0, '.', ' ');
return $remaining;
} elseif ($point <= $sixthlevel) {
$total = ($point/$sixthlevel) * 100;
$remaining = round($total);
//echo number_format($remaining, 0, '.', ' ');
return $remaining;
}
}
Try this:
function to_next_level($point) {
/*
**********************************************************************
*
* This function check how much points user has achievents and how much procent it is until next level
*
**********************************************************************
*/
$levelArray = array(3000, 7000, 15000, 28000, 45000, 80000);
foreach ($levelArray as $level)
{
if ($point <= $level) {
$total = ($point/$level) * 100;
$remaining = round($total);
//echo number_format($remaining, 0, '.', ' ');
return $remaining;
}
}
}
Start using OOP programming style. This is the perfect opportunity since it is a task without much complexity. Create a class that acts as central authority. That class can receive more methods over time. That way your code stays easy to maintain since all those functions are kept inside a class.
<?php
class levelAuthority
{
public static $thresholds = [ 3000, 7000, 15000, 28000, 45000, 80000 ];
public static function getDistanceToNextlevel($points)
{
foreach (self::$thresholds as $threshold) {
if ($points <= $threshold) {
$total = ($points/$threshold) * 100;
$remaining = round($total);
return $remaining;
}
}
}
}
// in the calling scope:
$points = 5000;
echo levelAuthority::getDistanceToNextlevel($points);
lots of answers to this!!
here is mine using a while loop - single exit point outside the loop:
function to_next_level($point) {
/*
**********************************************************************
*
* This function check how much points user has achievements and how much percent it is until next level
*
**********************************************************************
*/
$arr_level = array(3000,15000,28000,45000,80000);
$remaining = false;
while (!$remaining and list($key,$level) = each($arr_level)) {
if ($point <= $level) {
$total = ($point/$level) * 100;
$remaining = round($total);
}
}
// will return false if $point is greater than highest value in $arr_level
return $remaining;
}
You could write an additional function, that does the calculations and trigger it from the if/else if/else blocks.
function calculate_remaining($points, $level) {
$total = ($point/$level) * 100;
$remaining = round($total);
return $remaining;
}
You'd trigger this like:
if($point <= $firstlevel) {
return $calculate_remaining($point, $firstlevel);
} elseif ($point <= $secondlevel) {
return $calculate_remaining($point, $secondlevel);
} etc.
What about something like this?
function to_next_level($point)
{
$levels = array(
3000,
7000,
15000,
28000,
45000,
80000
);
foreach ($levels as $level)
{
if ($point <= $level)
{
$total = ($point / $level) * 100;
$remaining = round($total);
//echo number_format($remaining, 0, '.', ' ');
return $remaining;
}
}
}
The point levels are in order in the array, so [0] is $firstlevel, and so on. You simply iterate through the array and return whenever we reach the condition where $point is <= to the the $level.
Also, since $levels is static, it can be defined outside of the function.
simple:
<?php
$point = 100;
$remaining = 0;
$data = [
'firstlevel' => 3000,
'secondlevel' => 7000,
'thirdlevel' => 15000,
'forthlevel' => 28000,
'fifthlevel' => 45000,
'sixthlevel' => 80000
];
foreach($data as $item)
{
if($point <= $item)
{
$remaining = round(($point / $item ) * 100); //or return val
}
}
How about putting your variable into array and loop it?
function to_next_level($point) {
$data[0] = "3000";
$data[1] = "7000";
$data[2] = "15000";
$data[3] = "28000";
$data[4] = "45000";
$data[5] = "80000";
foreach ($data as $key => $value) {
if($point <= $value) {
$total = ($point/$value) * 100;
$remaining = round($total);
return $remaining;
}
}
}
I haven't try it. But it might work for you.

php array and array sum not returning right value

When i call this function on my webpage it should echo out the total value of the products in your shopping cart, But it only echo's out the value of the product with highest product id. Instead of the sum of these values combined.
function total_price() {
$total = 0;
global $link;
$ip = getIp();
$sel_price= "select * from cart where ip_add='$ip'";
$run_price= mysqli_query($link, $sel_price);
while($p_price=mysqli_fetch_array($run_price)) {
$pro_id = $p_price['id'];
$pro_price = "select * from products where id='$pro_id'";
$run_pro_price = mysqli_query($link, $pro_price);
while ($pp_price = mysqli_fetch_array($run_pro_price)){
$product_price = array($pp_price['prijs']);
$values = array_sum($product_price);
$total = number_format((float)$values, 2, ',', '');
}
}
echo "€ " .$total;
}
There's no reason to use array_sum. The sum of an array with one element is just the value of that element. You would use array_sum if you were pushing each price onto the array, and then calculating the sum at the end of the loop. But you can just add to the total value each time through the loop, so there's no need to do that.
while ($pp_price = mysqli_fetch_array($run_pro_price)){
$values += $pp_price['prijs'];
}
}
$total = number_format((float)$values, 2, ',', '');
echo "€" . $total;
You could also do everything in a single query:
$sel_total = "SELECT SUM(prijs) AS total
FROM cart
JOIN products ON cart.id = product.id
WHERE ip_add = '$ip'";
$res = mysqli_query($sel_total);
$row = mysqli_fetch_assoc($res);
$total = number_format($row['total'], 2, ',', '');
echo "€" . $total;
$total += number_format((float)$values, 2, ',', '');
should work
<?php
function total_price() {
$values = 0;
$total = 0;
global $link;
$ip = getIp();
$sel_price= "select * from cart where ip_add='$ip'";
$run_price= mysqli_query($link, $sel_price);
while($p_price=mysqli_fetch_array($run_price)) {
$pro_id = $p_price['id'];
$pro_price = "select * from products where id='$pro_id'";
$run_pro_price = mysqli_query($link, $pro_price);
while ($pp_price = mysqli_fetch_array($run_pro_price)){
//$product_price = array($pp_price['prijs']);
//this will cumulate sum
$values += $pp_price['prijs'];
//$total = number_format((float)$values, 2, ',', '');
}
}
//this will format result
$total = number_format((float)$values, 2, ',', '');
echo "€ " .$total;
}
btw why dont you try using JOIN statement???

How to get max value in loop

ok so im working with this loop and getting information from DB:
for($i0 = 0; $i0 < $total0; $i0 ++) {
$id = $oconecta->retrieve_value($i0, "id_tam_product");
$price = $oconecta->retrieve_value($i0, "price_tam_product");
echo $id; // RESULTS: 312, 313, 314
echo $price; // RESULTS: 180.00, 250.00, 300.00
}
i was wondering how can i get the MAX value for that loop:
echo $id; //RESULTS: 314
echo $price; //RESULTS: 300.00
$maxID = 0;
$maxPrice = 0;
for($i0=0;$i0<$total0;$i0++)
{
$id=$oconecta->retrieve_value($i0,"id_tam_product");
$price=$oconecta->retrieve_value($i0,"price_tam_product");
$maxID = max($id, $maxID);
$maxPrice = max($price, $maxPrice);
}
echo "MAX ID: $maxID - Max PRICE: $maxPrice";
Use the max() function to determine the highest number of a set.
Either you use SQL's MAX() if you can modify your SQL query, or keep the max value in a variable in each loop, and reassign it everytime:
$firstLoop = true;
$maxId = 0;
$maxPrice = 0;
for ($i0 = 0; $i0 < $total0; $i0++)
{
$id = $oconecta->retrieve_value($i0, "id_tam_product");
$price = $oconecta->retrieve_value($i0, "price_tam_product");
if ($firstLoop) {
$firstLoop = false;
$maxId = $id;
$maxPrice = $price;
}
else {
$maxId = max($maxId, $id);
$maxPrice = max($maxPrice, $price);
}
}
(the boolean is here if you have negative values it wouldn't work if $maxPrice and $maxId are initiliazed with 0)

Split total into 5 different numbers

Ok what i'm wanting to do is split a number ($row['count']) into 5, this is easy enough if you want equal numbers:
$sum = ($row['count'] / 5);
$fsum = floor($sum);
but I want each number to be different and still add up to total ie $row['count'] how can this be achieved?
Update:
If this helps its to be used to update 5 rows in a database:
$query = "SELECT * FROM foo";
$result = mysql_query($query);
while ($row = mysql_fetch_array($result)) {
$sum = ($row['count'] / 5);
$fsum = floor($sum);
$id = $row['id'];
$update = "UPDATE foo SET foo1='$fsum', foo2='$fsum', foo3='$fsum', foo4='$fsum', foo5='$fsum' WHERE id='$id'";
mysql_query($update);
}// while
so ideally the $update query would be something like:
$update = "UPDATE foo SET foo1='$fsum1', foo2='$fsum2', foo3='$fsum3', foo4='$fsum4', foo5='$fsum5' WHERE id='$id'";
This is my take:
function randomize($sum, $parts) {
$part_no = count($parts);
$continnue_counter = 0;
while (count(array_unique($parts)) != $part_no) {
$changing = array_rand($parts, 2);
if (($parts[$changing[0]] - 1) == 0 || ($parts[$changing[1]] - 1) == 0) { // don't let them go under 1
++$continnue_counter;
// sometime one element get everything and others even out on 1
// just throw away everything you got so far and start over
if ($continnue_counter > 10) {
$parts = setup($sum, $part_no);
$continnue_counter = 0;
}
continue;
}
$continnue_counter = 0;
$signum = mt_rand(0, 100) % 2 ? 1 : -1;
$delta = $signum * mt_rand(1, min($parts[$changing[0]] - 1, $parts[$changing[1]] - 1)); // -1 to make sure they don't go under 0
$parts[$changing[0]] += $delta;
$parts[$changing[1]] -= $delta;
}
return $parts;
}
function setup($sum, $part_no) {
$parts = array_fill(0, $part_no, (int)($sum / $part_no));
// acount for the reminder of (int) cast
$reminder = $sum - array_sum($parts);
while ($reminder) {
$parts[array_rand($parts)] += 1;
--$reminder;
}
return $parts;
}
$part_no = 5;
$sum = 42;
$parts = randomize($sum, setup($sum, $part_no));
var_export($parts);
print array_sum($parts)
Update:
I've added a version that introduces a little more entropy.
Update2:
The more random one had a tendency to decrement everything to 1 except one part, added an explicit detection to deal with this. Still the algorithm behind it has unknown termination time.

Categories