PHP: Counting entries in a loop and using them in a calculation - php

I have a loop in PHP as follows:
$getDetails = mssql_query ("SELECT * FROM BasketItems
WHERE BasketID = '".$_GET['id']."' ");
while ($detailsrow = mssql_fetch_array($getDetails)) {
$TotalSetPrice = $detailsrow['FinalPrice'] * $detailsrow['Qty'];
echo $TotalSetPrice;
$numberofent = count($detailsrow['FinalPrice']);
echo "######NUMBER#####: $numberofent";
$TotalPrice = ?????;
######VARIOUS DATA##############
}
So ok i'm not an expert at PHP by any means, thats the first thing. FinalPrice is the price of an item in the DB that someone has selected. However the customer can have any number of quantity of those items.
So FinalPrice * Qty = TotalSetPrice
However the customer may also have different sets of items within the basket.
So I need to calculate TotalSetPrice * (Number of sets of items Within the DB)
SO I googled, and came up with count(), but if I just count($detailsrow) it returns 56 entries, this is the number of overall pieces of data if that makes sense. I just want to count the dumber of actual data sets. I tried counting finalprice but that just returns 1, which isn't correct either.
Can anyone give me some guidence on how you are meant to count the number of entries in an array loop such as this. I hope that makes more sense than I feel it does.

SELECT FinalPrice, Qty,(FinalPrice * Qty) AS TotalSetPrice
Just use mysql, so that you no longer use with php which you will need to write a longer code

$TotalPrice += $TotalSetPrice;
This is short for: $TotalPrice = $TotalPrice + $TotalSetPrice;

Related

My cart items aren't printing in the same order in which they're placed

My code isn't printing the products in the order I placed them into the cart session. The product ids are as follow:
Apples value of 2
Blackberries value of 3
Green grapes value of 6
As you can see in the printed array, the order in which I placed them into the cart session is Grapes, Blackberries and then Apples but for some reason it's printing in the order of their given values rather than their cart order.
The code still treats each of the products as if they're in the correct place however. For example, Apples are suppose to be the third item in the cart array where the grapes currently are. If the quantity button of the grapes is changed, the quantity of Apples would be changed instead because it's still reading the array correctly.
I suspect the problems lie in one of the loops but I just can't seem to find what it is.
<?php
$total = 0;
$id_count = 0;
if(isset($_SESSION['cart']) and count($_SESSION['cart']) > 0){
$product_ID = array_column($_SESSION['cart'],"product_ID");
$result = $database->getData();
while($row = mysqli_fetch_assoc($result)){
foreach($product_ID as $id){
if($row['id']==$id){
print_r($product_ID);
print_r($row['product_name:']);
echo " value: $id";
$itemQuantity = $_SESSION['cart'][$id_count]['quantity'];
cartMethod($row['product_name'],$row['product_img'],$row['product_price'], $row['id'], $itemQuantity);
$total = $total + ($itemQuantity*(float)$row['product_price']);
$id_count++;
}
}
}
}
else{
echo "<h5>Cart is currently empty</h5>";
}
?>
This is the getData() function located in a different file.
//get method to retrieve database information
public function getData(){
$sql = "SELECT * FROM $this->tablename";
$result = mysqli_query($this->connection, $sql);
if(mysqli_num_rows($result)>0){
return $result;
}
}
You're iterating over the product catalog from the database ($database->getData()), and then for each entry in there crosschecking if it exists in $product_ID.
So the effective order follows that of the query (which is probably ORDER BY id or something i suspect (i can't tell; the code isnt included).
It's not hard to fix but you are building the cart in a very inefficient method here. It would make a lot more sense to do the bulk of data collation (which is what most of this page is), inside the database.
Of course, i don't know what the product catalog looks like in the database, and i don't know what query hides behind $database->getData(), so i cannot really give more targetted advice.
If i had to guess, i'd suspect that $database->getData() contains a query such as SELECT * FROM products ORDER BY productid ASC. If that is indeed the case then i would extend that query so you can feed the $_SESSION['cart'] data into the SELECT query, and join that against the products table.
That way:
A) you have full control over the ordering
B) you only have to return the relevant products and not "all" products, muchhh more efficient.
C) you dont have to mix&match the 2 datasets in PHP

Get database output as one

i this problem that i am sure are very simple to some people but atm i just cant wrap my head around it.. here goes i want to plus all data outputs from a certain row with the code i have now it just outputs for example 12 2 12 14 but i want to get 40 instead of the above just to state a example here is my code
$searchTimeScale = mysql_query("SELECT * FROM workhours WHERE case_project_id='$myCaseId'");
while($timeFeed = mysql_fetch_assoc($searchTimeScale)){
$workedHours = $timeFeed['worked_hours'];
$workedMinutes = $timeFeed['worked_minutes'];
echo $workedHours;
var_dump($workedMinutes);
}
You should use aggregate function SUM() along with GROUP BY
SELECT SUM(your_hour_field)
FROM workhours
WHERE case_project_id='$myCaseId'
GROUP BY case_project_id
You don't technically need GROUP BY here since you are only querying for a single case_project_id, but I am showing it in case you ever wanted to SUM up across a full record set with aggregations on a specific field or fields.
You can aggregate in your SQL query by selecting SUM(worked_hours*60+worked_minuts). That gives you the total number of minutes.
Just keep a counter going:
$total = 0;
while($timefeed = mysql_fetch_assoc(...))) {
$total += ($timeFeed['worked_hours'] * 60) + $timeFeed['worked_minutes'];
}

grand total sum in php

this may sound lame but i am stuck up with summing up the values retrieved from mysql.
i want to sum up the grand total of the sales invoice items that is retrieved from mysql database.
following is the code for sub total for each line which is fine.
while($row = mysql_fetch_array($qry)){
echo $row['b'] * $row['c'];
}
'b' is the quantity and 'c' is the price.all these values are retrieved from mysql and the no of rows is variable and all this is inside the while loop.
Now outside of the while loop, the last row, i want the grand total. can somebody point me in the right direction. i tried
echo SUM($row['b'] * $row['c']);
but this doesn't work and gives an error. i am sure i am doing it wrongly.
$total = 0;
while($row = mysql_fetch_array($qry))
{
echo $row['b'] * $row['c'];
$total += ($row['b'] * $row['c']);
}
// at the end, $total = grand total
Why not use SQL for things SQL does best?
SELECT SUM(b*c)
FROM table
Simple as that.

Database data in PHP array

I have a table in phpmyadmin that stores an 'id' (auto inc), 'title' and a 'date'.
I have a webpage where I display the 10 latest items (I simply order by ID).
On that page I print the title and the date. My wish is to also display the number of the posted item, so the first posted item is 1, the second is 2, etc. I cannot simply print the ID from the database because if I delete a row, the numbers aren't straight anymore.
My idea was to put all the data in an array but I have no clue what the best way to do this is and how I could print that item number. So for example when I want to display the 54th item I can easily print $items[54][id] or something and it will show me the number 54 and to display the title I print $items[54][title].
I don't know if there are simpler methods, plus arrays always start at 0, but my items must start at 1.
Besides this page that shows the 10 latest items, there is another page where it gets the title of the item out of the URL. How will I be able to search the title in the array and display the data the same way but only for that requested title?
Thanks in advance!
"SELECT COUNT(id) as cnt FROM mytable";
you can select the count of all database entries.
and then assign it to your iterator
$i = $row['cnt']; // this will hold the ammount of records e.g. 21
// other query
while($row = mysql_fetch_assoc($result)) {
echo $i;
$i--; // this will decrement on every iteration 21, 20 , 19, and so on.
}
First off. I would add a timestamp field to the database and order by that instead as it feels overall more reliable and gives you additional details which may prove handy later.
To create the multidimensional array I would do something like:
$result = mysql_query(...);
$items = array();
while($item = mysql_fetch_assoc($result)) {
$items[] = $item;
}
Now $items[12] for example would give you item number 13 (since it's 0-indexed).
Lastly, to select only the item with a specific title I would use a query which included a WHERE clause, like
"SELECT ... FROM ... WHERE title = '".$title."'"
It's very important to sanitize this variable before using it in the query though.
You can read more about MySQL on a lot of places. A quick googling gave me this: http://www.tutorialspoint.com/mysql/index.htm
You should learn PHP before starting to program in PHP ;) Read and work through the PHP manual and some tutorials!
As to your question it is a simple loop you want to do. One way of doing it as an example.
Fetch the 10 last items from the database in any way you like, following some code, partly pseudo-code.
$markup = '';
for ($i=1; $i<=count($items); $i++)
{
$markup .= 'Item ' . $i . ': ' . $items['date'] . ' - ' . $items['title'];
$markup .= 'read more';
$markup .= PHP_EOL;
}
echo $markup;
I don't know how you print out your data exactly, but I assume there is a loop in there. Simply set a counter that increments by one at every row and print its value.
As for the title search, you'll have to run another query with a WHERE title = '$title' condition, but beware of SQL injection.

How can I select a PHP variable that relates to a specific percentage chance?

I'm trying hard to wrap my head around what I'm doing here, but having some difficulty... Any help or direction would be greatly appreciated.
So I have some values in a table I've extracted according to an array (brilliantly named $array) I've predefined. This is how I did it:
foreach ($array as $value) {
$query = "SELECT * FROM b_table WHERE levelname='$value'";
$result = runquery($query);
$num = mysql_numrows($result);
$i=0;
while ($i < 1) {
$evochance=#mysql_result($result,$i,"evochance"); // These values are integers that will add up to 100. So in one example, $evochance would be 60, 15 and 25 if there were 3 values for the 3 $value that were returned.
$i++;
}
Now I can't figure out where to go from here. $evochance represent percentage chances that are linked to each $value.
Say the the favourable 60% one is selected via some function, it will then insert the $value it's linked with into a different table.
I know it won't help, but the most I came up with was:
if (mt_rand(1,100)<$evochance) {
$valid = "True";
}
else {
$valid = "False";
}
echo "$value chance: $evochance ($valid)<br />\n"; // Added just to see the output.
Well this is obviously not what I'm looking for. And I can't really have a dynamic amount of percentages with this method. Plus, this sometimes outputs a False on both and other times a True on both.
So, I'm an amateur learning the ropes and I've had a go at it. Any direction is welcome.
Thanks =)
**Edit 3 (cleaned up):
#cdburgess I'm sorry for my weak explanations; I'm in the process of trying to grasp this too. Hope you can make sense of it.
Example of what's in my array: $array = array('one', 'two', 'three')
Well let's say there are 3 values in $array like above (Though it won't always be 3 every time this script is run). I'm grabbing all records from a table that contain those values in a specific field (called 'levelname'). Since those values are unique to each record, it will only ever pull as many records as there are values. Now each record in that table has a field called evochance. Within that field is a single number between 1 and 100. The 3 records that I queried earlier (Within a foreach ()) will have evochance numbers that sum up to 100. The function I need decides which record I will use based on the 'evochance' number it contains. If it's 99, then I want that to be used 99% of the time this script is run.
HOWEVER... I don't want a simple weighted chance function for a single number. I want it to select which percentage = true out of n percentages (when n = the number of values in the array). This way, the percentage that returns as true will relate to the levelname so that I can select it (Or at least that's what I'm trying to do).
Also, for clarification: The record that's selected will contain unique information in one of its fields (This is one of the unique values from $array that I queried the table with earlier). I then want to UPDATE another table (a_table) with that value.
So you see, the only thing I can't wrap my head around is the percentage chance selection function... It's quite complicated to me, and I might be going about it in a really round-about way, so if there's an alternative way, I'd surely give it a try.
To the answer I've received: I'm giving that a go now and seeing what I can do. Thanks for your input =)**
I think I understand what you are asking. If I understand correctly, the "percentage chance" is how often the record should be selected. In order to determine that, you must actually track when a record is selected by incrementing a value each time the record is used. There is nothing "random" about what you are doing, so a mt_rand() or rand() function is not in order.
Here is what I suggest, if I understood correctly. I will simplify the code for readability:
<?php
$value = 'one'; // this can be turned into an array and looped through
$query1 = "SELECT sum(times_chosen) FROM `b_table` WHERE `levelname` = '$value'";
$count = /* result from $query1 */
$count = $count + 1; // increment the value for this selection
// get the list of items by order of percentage chance highest to lowest
$query2 = "SELECT id, percentage_chance, times_chosen, name FROM `b_table` WHERE `levelname` = '$value' ORDER BY percentage_chance DESC";
$records = /* results from query 2 */
// percentage_chance INT (.01 to 1) 10% to 100%
foreach($records as $row) {
if(ceil($row['percentage_chance'] * $count) > $row['times_chosen']) {
// chose this record to use and increment times_chosen
$selected_record = $row['name'];
$update_query = "UPDATE `b_table` SET times_chosen = times_chosen + 1 WHERE id = $row['id']";
/* run query against DB */
// exit foreach (stop processing records because the selection is made)
break 1;
}
}
// check here to make sure a record was selected, if not, then take record 1 and use it but
// don't forget to increment times_chosen
?>
This should explain itself, but in a nutshell, you are telling the routine to order the database records by the percentage chance highest chance first. Then, if percentage chance is greater than total, skip it and go to the next record.
UPDATE: So, given this set of records:
$records = array(
1 => array(
'id' => 1001, 'percentage_chance' => .67, 'name' => 'Function A', 'times_chosen' => 0,
),
2 => array(
'id' => 1002, 'percentage_chance' => .21, 'name' => 'Function A', 'times_chosen' => 0,
),
3 => array(
'id' => 1003, 'percentage_chance' => .12, 'name' => 'Function A', 'times_chosen' => 0,
)
);
Record 1 will be chosen 67% of the time, record 2 21% of the time, and record 3 12% of the time.
$sum = 0;
$choice = mt_rand(1,100);
foreach ($array as $item) {
$sum += chance($item); // The weight of choosing this item
if ($sum >= $choice) {
// This is the item we have selected
}
}
If I read you right, you want to select one of the items from the array, with some probability of each one being chosen. This method will do that. Make sure the probabilities sum to 100.

Categories