php array doesn't sum numbers - php

why doesn't this code sum my spent_hours for each user?
while ($row = $result->fetch_assoc())
{
$total_spent_time += $row['spent_time'];
if (!array_key_exists($row['activity_type'], $data))
{
$data[$row['activity_type']] = array(
'spent_time' => array('user' => array())
);
$data[$row['activity_type']]['spent_time']['user'][$row['user']] = array('time' => $row['spent_time']);
if (array_key_exists($row['user'], $data[$row['activity_type']]['spent_time']['user']))
{
$data[$row['activity_type']]['spent_time']['user'][$row['user']]['time'] += $row['spent_time'];
}
}
It gives me only the last value of the row.

Try to declare counter before loop:
$total_spent_time = 0;
while ($row = $result->fetch_assoc()) {
$total_spent_time += $row['spent_time'];
}
echo $total_spent_time;

You are doing wrong some where, we need some more details of query and resultset.You are not using $total_spent_time anywhere in the array allocation.
$data[$row['activity_type']]['spent_time']['user'][$row['user']] = array('time' => $row['spent_time']);
as you are only using $row['spent_time'], and since there is no second loop if statement executs only once per user($row['user'])That's the reason you get only 1 value.

Related

JSON decode foreach -> only delivery 1 row

my code only delivery 1 row. The first. This JSON contain 3000 rows.
Does anyone know why?
Thanks!
if (!empty($_GET["cuit"])){
$cuit = $_GET["cuit"];
$directorioDocs = 'data/docs/';
$data = file_get_contents("data/data.json");
$proveedores = json_decode($data, true);
$i = 0;
foreach ($proveedores as $proveedor) {
if ($cuit == $proveedor[$i]['cuit']) {
$proveedorArray = array(
"cuit" => $proveedor[$i]['cuit'],
);
}
else {$proveedorArray = array("Data" => "Debe ingresar un cuit");
}
$i = $i + 1;
}
echo json_encode($proveedorArray);
}
else
{
$proveedorArray = array("Data" => "Debe ingresar un cuit");
echo json_encode($proveedorArray);
}
$proveedorArray = array(
"cuit" => $proveedor[$i]['cuit'],
);
Creates a new array each iteration through the loop. You need to append instead:
// assuming each item in the parent array should be another array
$proveedorArray[] = array(
"cuit" => $proveedor[$i]['cuit'],
);
You'll also have to do the same in your else case inside the loop.
I tell you that the solution was found when analyzing the json
I did it with this tool->
https://jsonlint.com/
I'm missing this->
foreach ($proveedores['data'] as $proveedor) {
Also remove the index [0] that was already unnecessary
That was it
Thanks

CodeIgniter one query multiple statements

I use CodeIgniter, and when an insert_batch does not fully work (number of items inserted different from the number of items given), I have to do the inserts again, using insert ignore to maximize the number that goes through the process without having errors for existing ones.
When I use this method, the kind of data I'm inserting does not need strict compliance between the number of items given, and the number put in the database. Maximize is the way.
What would be the correct way of a) using insert_batch as much as possible b) when it fails, using a workaround, while minimizing the number of unnecessary requests?
Thanks
The Correct way of inserting data using insert_batch is :
CI_Controller :
public function add_monthly_record()
{
$date = $this->input->post('date');
$due_date = $this->input->post('due_date');
$billing_date = $this->input->post('billing_date');
$total_area = $this->input->post('total_area');
$comp_id = $this->input->post('comp_id');
$unit_id = $this->input->post('unit_id');
$percent = $this->input->post('percent');
$unit_consumed = $this->input->post('unit_consumed');
$per_unit = $this->input->post('per_unit');
$actual_amount = $this->input->post('actual_amount');
$subsidies_from_itb = $this->input->post('subsidies_from_itb');
$subsidies = $this->input->post('subsidies');
$data = array();
foreach ($unit_id as $id => $name) {
$data[] = array(
'date' => $date,
'comp_id' => $comp_id,
'due_date' => $due_date,
'billing_date' => $billing_date,
'total_area' => $total_area,
'unit_id' => $unit_id[$id],
'percent' =>$percent[$id],
'unit_consumed' => $unit_consumed[$id],
'per_unit' => $per_unit[$id],
'actual_amount' => $actual_amount[$id],
'subsidies_from_itb' => $subsidies_from_itb[$id],
'subsidies' => $subsidies[$id],
);
};
$result = $this->Companies_records->add_monthly_record($data);
//return from model
$total_affected_rows = $result[1];
$first_insert_id = $result[0];
//using last id
if ($total_affected_rows) {
$count = $total_affected_rows - 1;
for ($x = 0; $x <= $count; $x++) {
$id = $first_insert_id + $x;
$invoice = 'EBR' . date('m') . '/' . date('y') . '/' . str_pad($id, 6, '0', STR_PAD_LEFT);
$field = array(
'invoice_no' => $invoice,
);
$this->Companies_records->add_monthly_record_update($field,$id);
}
}
echo json_encode($result);
}
CI_Model :
public function add_monthly_record($data)
{
$this->db->insert_batch('monthly_record', $data);
$first_insert_id = $this->db->insert_id();
$total_affected_rows = $this->db->affected_rows();
return [$first_insert_id, $total_affected_rows];
}
AS #q81 mentioned, you would split the batches (as you see fit or depending on system resources) like this:
$insert_batch = array();
$maximum_items = 100;
$i = 1;
while ($condition == true) {
// code to add data into $insert_batch
// ...
// insert the batch every n items
if ($i == $maximum_items) {
$this->db->insert_batch('table', $insert_batch); // insert the batch
$insert_batch = array(); // empty batch array
$i = 0;
}
$i++;
}
// the last $insert_batch
if ($insert_batch) {
$this->db->insert_batch('table', $insert_batch);
}
Edit:
while insert batch already splits the batches, the reason why you have "number of items inserted different from the number of items given" might be because the allowed memory size is reached. this happened to me too many times.

Data present in multidimensional array are not displayed correctly

I'm trying to get the values from a Query String and add them to an array inside of an array. The output Query String is something like:
add_to_cart.php?product_id=4&product_name=Pizza&quantity=1&additional_id[]=1&additional_quantity[]=3&additional_id[]=4&additional_quantity[]=5
I'm getting each additional_id and additional_quantity variables presents in the Query String with the code below. I compare each of the additional_id with the IDs that I have in database table additionals and insert all into an array. The following code exists in my file add_to_cart.php file:
if(isset($_SESSION['cart']))
{
while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
extract($row);
$columns = array
(
'product_id_session' => $product_id_session,
'product_id' => $product_id,
'product_name' => $product_name,
'product_price' => $product_price,
'quantity' => $quantity,
'additionals' => array()
);
if(isset($_GET['additional_id']) && $_GET['additional_id'] != "")
{
foreach($_GET['additional_id'] as $additional => $value)
{
$additional_id = $value;
if(isset($_GET['additional_quantity'][$additional]))
{
$additional_quantity = $_GET['additional_quantity'][$additional];
if($additional_quantity <= 0 || $additional_quantity > 5)
{
$additional_quantity = null;
}
else
{
$sql2 = "SELECT additional_id, additional_name, additional_price FROM additionals WHERE additional_id LIKE '{$additional_id}'";
$stmt2 = $connection->prepare($sql2);
$stmt2->execute();
while ($row = $stmt2->fetch(PDO::FETCH_ASSOC))
{
extract($row);
$columns['additionals'][]['additional_id'] = $additional_id;
$columns['additionals'][]['additional_name'] = $additional_name;
$columns['additionals'][]['additional_price'] = $additional_price;
$columns['additionals'][]['additional_quantity'] = $additional_quantity;
}
}
}
}
}
$_SESSION['cart'][$product_id_session] = $columns;
}
header('Location: products.php?action=added&product_name=' . $product_name);
}
Once everything is added in the cart SESSION, in the cart.php page I'm trying to show the products with their selected additionals and quantities with:
foreach($_SESSION['cart'] as $product)
{
echo "<tr>";
echo "<td>{$product['product_name']}</td>";
echo "<td>${$product['product_price']}</td>";
echo "<td>{$product['quantity']}</td>";
echo "<td>";
foreach($product['additionals'] as $additional)
{
echo "<p>{$additional['additional_quantity']}x{$additional['additional_name']} - {$additional['additional_price']}</p>";
}
echo "</td>";
echo "</tr>";
}
But I'm doing something wrong, I think these two codes are not working properly.
My output is embarrassed, something like this:
Am I doing it by the right way? Maybe I'm not looping right with foreach, or the additionals are not being added with success? Sorry for the mistakes, I never worked with multidimensional arrays before. Is there a way to do what I am intending to? Thanks!
solution as per the comments-
Your issue is caused by $columns['additionals'][] as it is causing each value to being added as its own array. This is solved by added $additional as the array key -
while ($row = $stmt2->fetch(PDO::FETCH_ASSOC))
{
extract($row);
$columns['additionals'][$additional]['additional_id'] = $additional_id;
$columns['additionals'][$additional]['additional_name'] = $additional_name;
$columns['additionals'][$additional]['additional_price'] = $additional_price;
$columns['additionals'][$additional]['additional_quantity'] = $additional_quantity;
}
or you could also do-
while ($row = $stmt2->fetch(PDO::FETCH_ASSOC))
{
extract($row);
$columns['additionals'][] = array('additional_id' => $additional_id,
'additional_name' => $additional_name,
'additional_price' => $additional_price,
'additional_quantity' => $additional_quantity);
}

Create new array from existing array in php

Good Day
I have an array containing data seperated by a comma:
array (
[0]=>Jack,140101d,10
[1]=>Jack,140101a,15
[2]=>Jack,140101n,20
[3]=>Jane,141212d,20
[4]=>Jane,141212a,25
[5]=>Jane,141212n,30
)
There is a lot of data and I would like the data to be set out as:
array(
[Jack]=>
[140101]
=>[d] =>10
=>[a] =>15
=>[n] =>20
)
My code:
foreach ($out as $datavalue) {
$dat = str_getcsv($datavalue,',');
$datevalue = substr($dat[1],2,-1);
$shiftvalue = substr($dat[1],-1);
$totalvalue = $dat[2];
$sval[$shiftvalue] = $totalvalue;
$dval[$datevalue] = $sval;
$opvalue = $dat[0];
$final[$opvalue] = $dval;
}
Now it seems the array is populated even if there is no data from the original string, so my output shows results for Jack on the other dates even though there was no data for him originally. Hope this makes sense. Could anyone point out or suggest a solution please?
As mentioned in the comments, explode is what you need. See this working here.
<?php
$input = array (
0 => 'Jack,140101d,10',
1 => 'Jack,140101a,15',
2 => 'Jack,140101n,20',
3 => 'Jane,141212d,20',
4 => 'Jane,141212a,25',
5 => 'Jane,141212n,30',
);
$result = array();
foreach ($input as $key => $value) {
$valueParts = explode(',',$value); // now valueparts is an array like ('Jack','140101d','10')
$namePart = $valueParts[0];
$idPart = substr($valueParts[1],0,-1); // we need to strip the letter from the id
$charPart = substr($valueParts[1],-1); // and the id from the letter
$nrPart = $valueParts[2]; // you could use intval() to make this an integer rather than a string if you want
// Now we fill the array
if(!array_key_exists($namePart, $result)) {
$result[$namePart] = array();
}
if(!array_key_exists($idPart, $result[$namePart])) {
$result[$namePart][$idPart] = array();
}
if(!array_key_exists($charPart, $result[$namePart][$idPart])) {
$result[$namePart][$idPart][$charPart] = $nrPart;
}
}
var_dump($result);

change key names in array in php

ok..I'm trying to re-map the keynames of a key-value array in php using a fieldmap array ie.
i want the $outRow array to hold $inRow['name1'] = 10 to $outRow['name_1'] = 10 for a large set of pre-mapped values..
$fieldmap=array("name1"=>"name_1","name2"=>"name_2");
private function mapRow($inRow) {
$outRow = array();
foreach($inRow as $key => $value) {
$outRow[$this->fieldmap[$key]][] = $value;
}
return $outRow;
} // end mapRow
public function getListings($inSql) {
// get data from new table
$result = mysql_query($inSql);
if (!result) {
throw new exception("retsTranslate SQL Error: $inSql");
}
while ($row = mysql_fetch_assoc($result)) {
$outResult[] = $this->mapRow($row);
}
return $outResult;
} // end getListings
this is not working..I'm getting the array but its using $outResult[0][keyname]...I hope this is clear enough :)
$fieldmap=array("name1"=>"name_1","name2"=>"name_2");
private function mapRow($inRow) {
$outRow = array();
foreach($inRow as $key => $value) {
$outRow[$this->fieldmap[$key]][] = $value;
}
return $outRow;
} // end mapRow
while ($row = mysql_fetch_assoc($result)) {
//$outResult[] = $this->mapRow($row);
$outResult[= $this->mapRow($row);
}
I commented your line of code and added new one..it definitely got what you mentioned in question.
If you can structure your arrays to where the keys align with the values (see example below) you can use PHP array_combine(). Just know that you will need to make absolutely sure the array is ordered correctly.
<?php
$fieldmap = array( 'name_1', 'name_2', 'name_3' );
private function mapRow($inRow)
{
$outRow = array_combine( $this->fieldmap, $inRow );
return $outRow;
}
For example, if your array was:
array( 'name1' => 10, 'name2' => 20, 'name3' => 30 );
The new result would be:
array( 'name_1' => 10, 'name_2' => 20, 'name_3' => 30 );
Let me know if this helps.
Try this:
function mapRow($inRow) {
$outRow = array();
foreach($inRow as $key => $value) {
$outRow[preg_replace('/\d/', '_$0', $key,1)] = $value;
}
return $outRow;
}

Categories