php problem having the sum of values in a loop - php

I'm new in php and got stuck doing a loop.
I have the following:
an array containing 0 or not named $receivers.
another array containing total of receivers which is a number, named $totalreceivers.
a function querying a table with the id, returning 0 or number, named status().
I want to loop through each status() of the receivers and show the sum at the end. I couldn't get it.
Any help will be appreciated. Thanks in advance.
Here is what I tried:
for ($i = 0; $i < $totalreceivers; $i++)
{
$status = status($receivers[$i]);
foreach ($totalreceivers as $value)
$status = status($receivers[$i]);
echo "the sum of receiver having status different than 0 is";
echo count($status);
}
function status($id)
{
global $dbhost;
global $dbuser;
global $dbpass;
global $dbname;
global $d1;
$q2 = mysql_query("select * from user where id ='$id' AND subscription_end_date IS NULL", $d1);
while($row2 = mysql_fetch_array($q2))
$rowservice = $row2['value'];
return $rowservice;
}

A couple things in your code don't really make sense. First, you're trying to iterate through $totalreceivers twice, one loop being nested in the other. I doubt that's what you want so you should get rid of one of them. And your first loop has a bad expression: to iterate through $totalreceivers in your first for loop, you need to have your testing expression go against the number of elements in the array and not the array itself (can use count()): for ($i = 0; $i < count($totalreceivers); $i++).
Second, you're resetting the value of $status each time you call status() in your loop. To add to it, use the += operator: $status += status($receivers[$i]);
Third, you're doing the same in status() function with $rowservice; resetting it each iteration of that while loop. Either set it once, or sum it up.

You can simplify this task by letting MySQL do more of the work for you.
You have an array $receivers which presumably contains id's for subscribers to (receivers of) something. (I may use receiver and subscriber interchangeably.)
The status() function retrieves from the database the value for each receiver where the subscription_end_date is null. I am going to assume that there is only one row per subscriber because you only return the last result via the variable $rowservice.
It's unclear from your code if you want a count of receivers with a value other than 0, or if you want a sum of all non-zero values. The question then is:
Do you want to know how many subscribers have nonzero values? or,
Do you want to know the sum of all values for subscribers with nonzero values?
Fortunately both of these can be easily found:
How many receivers have non-zero values?
$allreceivers = implode(',', $receivers);
$query = "SELECT COUNT(id) AS total_receivers
FROM user
WHERE subscription_end_date IS NULL
AND value != 0
AND id IN ($allreceivers);";
$result = mysql_query($query, $d1);
$row = mysql_fetch_array($result);
$total_receivers = $row['total_receivers'];
echo "The number of receivers having status (value) other than 0 is $total_receivers";
What is the sum of all receiver values?
$allreceivers = implode(',', $receivers);
$query = "SELECT SUM(value) AS receiver_value_sum
FROM user
WHERE subscription_end_date IS NULL
AND id IN ($allreceivers);";
$result = mysql_query($query, $d1);
$row = mysql_fetch_array($result);
$receiver_value_sum = $row['receiver_value_sum'];
echo "The sum of receiver values is $receiver_value_sum";

At first glance, it looks like you are just overwriting "$status" on each iteration. Before the loop starts, set $status to an empty array and then add to it on each iteration. For example:
$status = array();
foreach ( $totalreceivers as $value)
{
$status[] = status($receivers[$i]);
}
echo count($status);

I will try to outline some possible problems with your code below:
for ($i = 0; $i < $totalreceivers; $i++) { //This open bracket has no end bracket
/*I assume total receivers is the number of receivers; if that is the case, it shouldn't be an array, but merely a value.*/
$status = status($receivers[$i]);
/*I think you should define the status function before you call it; also, if you are just calling the status function for each value of $receivers, why don't you just do a foreach($receivers as $value) loop, like you did below with $totalreceivers. */
foreach ( $totalreceivers as $value)
/*I'm not sure what $totalreceivers is. You said its an array containing total number of receivers; again, I would think this would be a single value, and not an array*/
{
$status = status($receivers[$i]);
/*looks like you're calling the status function again*/
}
echo "the sum of receiver having status different thant 0 is"; echo count($status);
/* $status at this point would count the value from row2 for the last value in $receivers, and not a count of array values. Perhaps you could do $status[] = status($receivers[$i]), and then count($status) to save each value to an array, then count the elements. */
function status($id){
global $dbhost;
global $dbuser;
global $dbpass;
global $dbname;
/* The values above aren't used in the function; you may want to connect to the database outside of the function, before the foreach loop. */
global $d1 ;
$q2 = mysql_query("select * from user where id ='$id' AND subscription_end_date IS NULL",$d1);
while($row2 = mysql_fetch_array($q2)){
$rowservice = $row2['value'];
}
return $rowservice;
}
/*the rest looks good*/

Related

How to check array for existing elements to assign ticket numbers?

I am attempting to create a function which will tell me what free numbers are available to use, I have a function which returns the numbers which have already been taken in an array.
I wish to check the returned array with existing elements against a blank array, and if the number is not in the array then push/add it to the empty array to allow me to return an array of available numbers/tickets.
I have tried some examples on here and looked upon PHP documentation on some items trying array_intersect, in_array etc.
I believe the best way to add the free numbers to the empty array is using array_push which has not been implemented into the example code as of yet.
Available numbers function so far:
function freeNumbers($drawID){
$minTickets = 1;
$maxTickets = totalTickets($drawID);
$takenNumbers = takenNumbers($drawID);
$freeNumbers = array();
for($i = 1; $i<$maxTickets; $i++){
$x = $i-1;
foreach($takenNumbers as $v){
if(in_array($v, $freeNumbers)){
echo "Element is in array";
break;
} else {
echo $v . "is taken";
}
}
}
//return $freeNumbers;
}
Taken numbers function
function takenNumbers($drawID){
$connect = new mysqli("localhost", "root", "", "dream");
$stmt = $connect->prepare("SELECT * FROM transaction WHERE DrawID = ?");
$stmt->bind_param("i", $drawID);
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows == 0) exit("No rows");
$tickets = array();
while($row = $result->fetch_assoc()){
$id = $row['ID'];
$tickets[] = $row['TicketNumber'];
}
return $tickets;
}
Max tickets is just counting from a database transaction table to count already assigned numbers.
In this current iteration of the project, I am receiving the following "1 is taken" for each loop.
Thanks in advance, I have attempted to explain what I am attempting to do in best terms possible. But if I haven't been able to describe something please reply so I can explain it further.
Instead of checking on each array item, you could get the the difference values between all of the ticket numbers and the taken ticket numbers array using array_diff() :
function freeNumbers($drawID){
$minTickets = 1;
$maxTickets = totalTickets($drawID);
$takenNumbers = takenNumbers($drawID);
$freeNumbers = array();
$allTickets = range(1, $maxTickets);
$freeNumbers = array_values(array_diff($allTickets, $takenNumbers));
//return $freeNumbers;
}
Edit : added array_values() to reset the array index returned from the array_diff() function.
Edit : Or if you prefer to use the array_push() function, you could do it like :
for($i = 1; $i<$maxTickets; $i++){
if(!in_array($i, $takenNumbers)){
array_push($freeNumbers, $i);
}
}

Pushing values and keys to an multidimensional array from the database inside a foreach loop without repetitions

I'm trying to combine two tables from a database, and based on my first one, I want to retrieve some value from the other one, and add them to an array.
Here's my problem:
My first database looks like that:
FIRST TABLE:
id, credit_type, association_name, address, city, province, postal_code, country, cycle_type, cycle_begin, cycle_months
My second database instead looks like that:
SECOND TABLE:
id, association_id, designation_name
The id in my first table matches the association_id in my second table so I don't need an INNER JOIN.
My approach is the following:
<?php
public function my_function()
{
$sql = ee()->db->select('*')->from('first_table')->get();
$data['database'] = [];
if ($sql->num_rows() > 0)
{
foreach($sql->result_array() as $row)
{
$id[] = $row['id'];
$data['database'][] = $row;
}
}
foreach ($data['database'] as $key => $value) {
$association_query = ee()->db->query("SELECT * FROM second_table WHERE id = $id");
foreach($association_query->result_array() as $row_two)
{
if ($association_query->num_rows() > 0)
{
$data['database'][$key]['associations'][] = $row_two['designation_name'];
}
}
}
return ee()->load->view('index', $data, true);
}
?>
The sintax ee()->db->select('*') is a prepared statment from expression engine and it's equal to SELECT * FROM first_table (sanitaized).
So as you can see, I try to pass the value $id, which is an array, to my query. The thing is that as soon as I push the value like that $id[] = $row['id'] I create a nice array, but when I loop through my foreach loop, it multiplies my array in many other arrays so I'm not able to run my query, even if I'm technically in a foreach loop.
Plus, as soon as I try to push the result of my query in my array, let's say changing the id in a static id for instance id=3, I obtain a really weird result, like so many arrays repeated with 1 value, 2 value, 3 value and so on, when I'd like to push my key 'association' only where it is presented in the other table.
If you won't do it on SQL, at least don't execute the second query so many times.
<?php
public function my_function()
{
$assocs = array();
$data = array('database' => array());
$association_query = ee()->db->query("SELECT * FROM second_table");
if ($association_query->num_rows() > 0) {
foreach($association_query->result_array() as $row) {
$assocs[$row['association_id'][] = $row['designation_name'];
}
}
$sql = ee()->db->select('*')->from('first_table')->get();
if ($sql->num_rows() > 0) {
foreach($sql->result_array() as $row) {
$id_check = $row['id'];
if (isset($assocs[$id_check])) {
$row ['associations'] = $assocs[$id_check] ;
}
$data['database'][] = $row;
}
}
return ee()->load->view('index', $data, true);
}
?>
Regards

PHP run query off each array variable and return results in table

I am trying to run a query off multiple array variables and display the results in a table.
The user selects 1 or more records, which includes BOL and CONTAINER. These selections are put in their own arrays and they are always an equal amount.
<?php
$bolArray = explode(',', $_POST['BOL']);
$containerArray = explode(',', $_POST['CONTAINER']);
$count = count($bolArray); // to get the total amount in the arrays
I use a FOR loop to separate each value from the 2 arrays:
for($i = 0; $i < $count; $i++)
{
$bol = $bolArray[$i];
$container = $containerArray[$i];
}
Here is the part where I'm stuck and probably where I am messing up.
I need to take each variable from the FOR loop and run query using both variables.
First, I'll start the table:
echo "<table><thead><tr><th>BOL</th><th>Container</th></thead><tbody>";
Here is where I tried a FOREACH loop:
foreach($containerArray as $container) // I am not sure if I am using this FOREACH correctly
{
And now, the query. Please take note of the variables from the first FOR loop:
$preQuery = "SELECT * FROM mainTable WHERE CONTAINER = '".$container."' AND BOL = '".$bol."'";
$preRes = mysql_query($preQuery) or die(mysql_error());
$preNum = mysql_num_rows($preRes);
I use a WHILE loop with a mysql_fetch_assoc:
while($preRow = mysql_fetch_assoc($preRes))
{
echo '<tr>'
echo '<td>'.$preRow[BOL_NUMBER].'</td>';
echo '<td>'.$preRow[CONTAINER_NUMBER].'</td>';
echo '<td>'.$preRow[ANOTHER_COLUMN].'</td>';
echo '</tr>'
}
}
echo '</tbody></table>';
?>
The query actually works. Problem is, it only returns 1 record, and it's always the last record. The user could select 4 records, but only the last record is returned in the table.
I tried to use the same query and paste it inside the first FOR loop. I echoed out the query and it displayed the same amount of times as the number of array values, but will only return data for the last record.
I do not understand what I am doing wrong. I just want to display data for each value from the array.
Edit
Here is what the code looks like when I throw the query in the first FOR loop:
echo "<table class='table table-bordered'><thead><tr><th>BOL</th><th>Container</th></tr></thead><tbody>";
for($i = 0; $i < $count; $i++)
{
$bol = $bolArray[$i];
$container = $containerArray[$i];
$preQuery = "SELECT BOL_NUMBER, CONTAINER_NUMBER FROM `intermodal_main_view` WHERE BOL_NUMBER = '". $bol ."' AND CONTAINER_NUMBER = '".$container."'";
$preRes = mysql_query($preQuery) or die();
$preNum = mysql_num_rows($preRes);
while($preRow = mysql_fetch_assoc($preRes))
{
echo '<tr>';
echo '<td>'.$preRow[BOL_NUMBER].'</td>';
echo '<td>'.$preRow[CONTAINER_NUMBER].'</td>';
echo '</tr>';
}
}
echo "</tbody></table>";
I think you can use "IN" if your POST vars are comma separated.
$preQuery = "
SELECT * FROM mainTable
WHERE CONTAINER IN ($_POST['CONTAINER'])
AND BOL IN ($_POST['BOL'])
";
$preRes = mysql_query($preQuery) or die(mysql_error());
$preNum = mysql_num_rows($preRes);
Then go to your while loop....
This would omit the need for creating an array and looping it.
Also, you need to switch to PDO for your query, and switch to parameter binding. It will take all of an hour to learn.

Separating mysql fetch array results

i have a mysql table the contains an index id, a data entry and 10 other columns called peso1, peso2, peso3...peso10. im trying to get the last 7 peso1 values for a specific id.
like:
$sql = mysql_query("SELECT * FROM table WHERE id='$id_a' ORDER BY data DESC LIMIT 0, 7");
when i try to fetch those values with mysql_fetch_array, i get all values together.
example:
while($line = mysql_fetch_array($sql)) {
echo $line['peso1'];
}
i get all peso1 values from all 7 days together. How can i get it separated?
They will appear all together because you are not separating them as you loop through them.
for example, insert a line break and you will see them on separate lines
while($line = mysql_fetch_array($sql)) {
echo $line['peso1'] ."<br />";
}
You could key it as an array like so
$myArray = array();
$i = 1;
while($line = mysql_fetch_array($sql)) {
$myArray['day'.$i] = $line['peso1'];
$i++;
}
Example use
$myArray['day1'] // returns day one value
$myArray['day2'] // returns day two value
It's not clear what you mean by "separated" so I'm going to assume you want the values as an array. Simply push each row field that you want within your while loop onto an array like this:
$arr = array();
while($line = mysql_fetch_array($sql)) {
$arr[]=$line['peso1'];
}
print_r($arr);//will show your peso1 values as individual array elements

How to use arrays to store values fetch from sql query in php

What I want to do here is to be able to assign the values from sql query into arrays.
And then compute for the total.
<?php
include('conn.php');
$qreports=query_database("SELECT S_PRICE, PID, QTY_PUR, ITEM_ID, CUSID, CNUM, Cust_Name, TDATE FROM prod_table, customer_credit, sales_trans_items WHERE prod_table.PID=sales_trans_items.ITEM_ID AND sales_trans_items.CNUM=customer_credit.CUSID AND sales_trans_items.TDATE='2011-02-06 09:14:09'","onstor",$link);
$grandtotal=0;
$customer="";
while($qrep=mysql_fetch_assoc($qreports)){
$pid=$qrep['PID'];
foreach ($pid as $k => $v) {
$sids=$v;
$qtypur=$qrep['QTY_PUR'][$k];
$sprice=$qrep['S_PRICE'][$k];
$customer=$qrep['Cust_Name'][$k];
$tdate=$qrep['TDATE'][$k];
$stot=$qtypur * $sprice;
$grandtotal =$grandtotal + $stot;
}
}
echo "Customer: ". $customer."<br/>";
echo "Profit: ". $grandtotal;
?>
I tried the query on phpmyadmin before I place it in the code, and it output this:
I think you misunderstood how mysql_fetch_assoc works: Every call returns one row from the result set. $grep is an array with structure columnname => value.
That also means that $qrep['PID'] cannot be an array and your foreach loop won't work. In every loop, $qrep['PID'] contains one of the values you see in the PID column in your screen shot.
I suggest you add print_r($qreq); in your while loop so you get more familiar with the structure of the array.
As each $qrep is an array itself, creating a result array is just adding each of these to a new array:
$result = array();
while(($qrep=mysql_fetch_assoc($qreports))) {
$result[] = $qrep;
}
Now you are performing some more computation where I am not sure what you want to get in the end but it seems you are multiplying each QTY_P with S_PRICE:
$total = 0;
foreach($result as $report) {
$total += $report['QTY_P'] * $report['S_PRICE'];
}
(You could however also compute this in your while loop)
Assuming you want to get the overall sum and the sum for each customer:
$total = 0;
$total_per_customer = array();
foreach($result as $report) {
$customer = $report['Cust_Name'];
if(!array_key_exists($customer, $total_per_customer)) {
$total_per_customer[$customer] = 0;
}
$price = $report['QTY_P'] * $report['S_PRICE'];
$total_per_customer[$customer] += $price;
$total += $price;
}
In the end, $total_per_customer is an array with customer names as keys and the sum of the prices as values. $total will contain the sum of all prices.
You question is a bit unclear, but i think the answer wont be far a way from the following suggested references:
As you loop through the rows use
something like $array[] =
$qrep['columnName'] to populate an
array.
Then, check out PHP's array_sum().

Categories