Updating database with foreach is changing the array before updating - php

I have an array with names, goal differences and so on for football teams that I want to put in a table, but during the foreach the last key in the array is changed somehow.
Last two keys before foreach
[18] => Array
(
[team_code] => 4
[team_name] => Newcastle
[points] => 6
[goals_for] => 12
[goals_against] => 22
[goal_difference] => -10
)
[19] => Array
(
[team_code] => 7
[team_name] => Aston Villa
[points] => 4
[goals_for] => 9
[goals_against] => 17
[goal_difference] => -8
)
)
After foreach
[18] => Array
(
[team_code] => 4
[team_name] => Newcastle
[points] => 6
[goals_for] => 12
[goals_against] => 22
[goal_difference] => -10
)
[19] => Array
(
[team_code] => 4
[team_name] => Newcastle
[points] => 6
[goals_for] => 12
[goals_against] => 22
[goal_difference] => -10
)
)
My foreach looks like this
foreach ($teams as $team) {
$team_code = $team['team_code'];
$team_name = $team['team_name'];
$points = $team['points'];
$goals_for = $team['goals_for'];
$goals_against = $team['goals_against'];
$goal_difference = $team['goal_difference'];
if ($update_query = $conn->query("UPDATE teams SET points = $points, goals_for = $goals_for, goals_against = $goals_against, goal_difference = $goal_difference WHERE team_code = $team_code")) {
echo 'Updated '.$team_name.'<br>';
} else {
$update_query->error;
}
}
Why is the last key changed? It happens before the query is run, because the row doesn't get updated. All the others update as they should.

Thanks to VolkerK I managed to solve it.
I have another foreach with a reference to &$team before the foreach, and putting unset($team) between the two foreachs solved the problem.

I don't think that there's anything wrong with your php script. I would take a look at how the array is build before it get to the foreach loop. How is the form for which you enter the data set up. If you are entering multiple teams at once, how are you differentiating the elements

Related

Create PHP Array Where Matching Keys have Some Value

This is the first post from a PHP noob. My question relates to an HTML/PHP form which posts the following three types of data generated by a MySQL query:
ID (always posted via a hidden input field)
Mileage (only some entries may be completed, others might be left blank)
Vehicle Type (always posted via a hidden input field)
This data is all for one of three companies that are selected on the page preceding the data-posting page ie.
Step One: Choose company and year. Press submit.
Step Two: See results from MySQL query and enter in mileages where necessary. Press submit.
Step Three: (that's why I'm here)
I've stuffed this data into what I (probably mistakenly) believe is a multidimensional array called $idmilearray by using the following code:
if(isset($_POST['mileage'])) {
$mileagenumber = $_POST['mileage'];
}
if(isset($_POST['idnos'])) {
$idnumber = $_POST['idnos'];
}
if(isset($_POST['vehicle'])) {
$vehicletype = $_POST['vehicle'];
}
$idmilearray = array(
'ids' => $idnumber,
'mileage' => $mileagenumber,
'vtype' => $vehicletype
);
foreach($idmilearray as $inputs) {
$inputs = $idmilearray['ids'];
$inputs = $idmilearray['mileage'];
$inputs = $idmilearray['vtype'];
}
If I execute a print_r on the $idmilearray I get the following results:
Array
(
[ids] => Array
(
[0] => 35
[1] => 22
[2] => 32
[3] => 38
[4] => 36
[5] => 39
[6] => 16
[7] => 20
[8] => 48
[9] => 46
)
[mileage] => Array
(
[0] => 334
[1] => 56
[2] =>
[3] => 43
[4] =>
[5] =>
[6] =>
[7] =>
[8] => 11
[9] => 5
)
[vtype] => Array
(
[0] => 10T
[1] => 10T
[2] => 10T
[3] => Artic
[4] => 10T
[5] => Artic
[6] => Artic
[7] => 10T
[8] => Artic
[9] => 10T
)
What I would like to do is to create another array (the values of which I can use in later SQL queries) but only where the keys contain something in [ids][0], [mileage][0] and [vtype][0] and so on and so forth. I'd like to use [mileage] as the 'reference array'.
I've been playing around with array_intersect_key and array_diff_key but I've hit a big and rather a nasty wall. Can anyone help or give some pointers?
Thanks very much for your time.
Regards,
External.
You can use what you have to insert directly into mysql as follows:
foreach ( $idmilearray['mileage'] as $KEY => $VAL ) {
if ( empty($VAL) ) continue;
$query = "INSERT INTO `tableName` (id, mileage, vtype) VALUES ('{$idmilearray['ids'][$KEY]}', '$VAL', '{$idmilearray['vtype'][$KEY]}')";
}
Or if you really want to merge everything for further processing or whatever reason you can do it like so:
$NewArray = [];
foreach ( $idmilearray['mileage'] as $KEY => $VAL ) {
if ( empty($VAL) ) continue;
$NewArray[] = array('id' => $idmilearray['ids'][$KEY], 'mileage' => $VAL, 'vtype' => $idmilearray['vtype'][$KEY]);
}
Ofcourse there are many other possible ways to do this, but these are the easiest given what you currently have.
Just add another foreach, inside your existing foreach and fill your new array by checking the old array values with if (!empty($old_array)) {}
Example:
foreach($idmilearray as $inputs) {
$inputs = $idmilearray['ids'];
$inputs = $idmilearray['mileage']; // This is the one you want, right?
$inputs = $idmilearray['vtype'];
}
To do the job you need, it would be something like this:
$new_array = []; // Short array syntax (PHP 5.3+)
foreach($idmilearray as $inputs) {
$inputs = $idmilearray['ids'];
foreach($idmilearray['mileage'] as $mileage) {
if (!empty($mileage)) {
$new_array[] = $mileage;
}
}
$inputs = $idmilearray['vtype'];
}
Now you have new array ($new_array) filled only with the keys that links to existing values.
I hope it helps you.

Codeigniter. How to check for duplicates in nested array and update it if duplicates exist?

How to check if nested array contains duplicates? if it does contain duplicate then how to update it?
Example
Array
(
[0] => Array
(
[pre_order_id] => 10
[product_id] => 1
[product_quantity] => 11
[product_unit_id] => 2
[storage_location_id] => 1
[price] => 1111
)
[1] => Array
(
[pre_order_id] => 10
[product_id] => 1
[product_quantity] => 11
[product_unit_id] => 2
[storage_location_id] => 1
[price] => 1111
)
[2] => Array
(
[pre_order_id] => 10
[product_id] => 3
[product_quantity] => 11
[product_unit_id] => 2
[storage_location_id] => 1
[price] => 1111
)
)
Here product_id is duplicated on two occasions .i want to keep only one and also update the quantity of it by adding the product_quantity of the other array which will be discarded.
I have tried this
// $input = array_map("unserialize", array_unique(array_map("serialize", $data_array)));
But it only removes duplicates not update .
If you want to do this in pure PHP you can use something like this:
function cleanDuplicates($aInput) {
$outPutArray = array();
foreach($aInput as $element) {
if(!isset($outPutArray[$element["product_id"]])) {
$outPutArray[$element["product_id"]] = $element;
}
else {
$outPutArray[$element["product_id"]]["product_quantity"] += $element["product_quantity"];
}
}
return $outPutArray;
}
After removing duplicates.You have to use $this->db->update_batch() for updating multidimensional array. Like this..
$this->db->update_batch('table_name',$input,$product_id);
For more see Codeigniter Query Builder

Cycling as an array returned by the method fetch_assoc () PHP & Mysqli

I ask those who have a bit of kindness to help me in this thing, I would like to cycle this dynamic array returned from a store procedure mysql, since it is dynamic and will never know the index I have no idea how to do, I know only the array with two key is the title that will give the list and arrays with [NomeProdotto] etc .. will list items.
This is Array to loop:
Array
(
[0] => Array
(
[NomeMenu] => Pizze
[IDMenu] => 1
)
[1] => Array
(
[IDMenu] => 1
[IDProdotto] => 2
[NomeProdotto] => Eurobar
[PrezzoProdotto] => 5.00
[IngredientiProdotto] => Pomodoro, Mozzarella, Patate bollite, Prosciutto
)
[2] => Array
(
[IDMenu] => 1
[IDProdotto] => 4
[NomeProdotto] => Parripusu
[PrezzoProdotto] => 6.00
[IngredientiProdotto] => Pomodoro, Mozzarella, Salsiccia, Funghi, Origano
)
[3] => Array
(
[IDMenu] => 1
[IDProdotto] => 5
[NomeProdotto] => U Chianu a Muccusa
[PrezzoProdotto] => 4.00
[IngredientiProdotto] => Pomodoro, Mozzarella, Origano
)
[4] => Array
(
[IDMenu] => 1
[IDProdotto] => 6
[NomeProdotto] => Vaddruni
[PrezzoProdotto] => 5.00
[IngredientiProdotto] => Pomodoro, Mozzarella, Piselli, Uovo, Prosciutto cotto, Funghi, Origano
)
[5] => Array
(
[NomeMenu] => Supplementi
[IDMenu] => 3
)
[6] => Array
(
[IDMenu] => 3
[IDProdotto] => 8
[NomeProdotto] => Prosciutto
[PrezzoProdotto] => 1.00
[IngredientiProdotto] =>
)
)
I solved this way
$i = 0;
$menus = array();
if ($mysqli->multi_query("CALL getMenuLocale(" . $_REQUEST['locale'] . ")")) {
while ($mysqli->more_results()) {
$mysqli->next_result();
if ($result = $mysqli->store_result()) {
while ($row = $result->fetch_all(MYSQL_ASSOC)) {
$menus[$i] = $row;
}
$result->free();
}
$i++;
}
}
but I get an error as soon as published on Godaddy :
Fatal error: Call to undefined method mysqli_result::fetch_all() on line 758
I read that the solution might be to use fetch_assoc () instead of fetch_all (), and it returns the array mentioned above, how can I cycle through php
First of all, don't use fetch_all. As the name implies, it returns the complete dataset. So use fetch_assoc, this will return a row of the result in the form of an array.
Like this:
while ($row = $result->fetch_assoc()) {
//
}
This leaves you with $row being the array with the irregular number of elements. You can also iterate through this array. So the code would look like:
while ($row = $result->fetch_assoc()) {
foreach ($row as $key => $value) {
//$key is 'IDMenu' for example
//$value is '1' for example
//you can then use these variables
}
}
This way it doesn't matter if you have 2 of 5 elements in the array, you can still use what values you have.
I also see you are trying to add the $row array to another $menus array? What is the purpose of this? Because you are essentially recreating the query result this way...
All things aside, perhaps it is a good idea to look at some tutorials if you have a hard time with working with arrays ;)

How to find number of inbound links in php if i have array of linking between pages?

I have this 2d array that represent outgoing links of each page returned by search engine, now I have to find number of inbound links of each page.
eg 1 is present in sub array in key2,3,4,5,6 so its number of inbound will be 5.
I need this in PHP.
$links = array(
1 => array(2,3,4,5,6),
2 => array(1,3,4,5,6),
3 => array(1,2,4,5,6),
4 => array(1,2,3,5,6),
5 => array(1,2,3,4,6),
6 => array(1,2,3,4,5),
7=> array (11),
8=>array(7,9),
9=> array(7),
10=> array(8),
11=> array(8,10),
);
probably a cleaner way, but one way is to create a new array, loop over your existing array, and add to the new array using the value as the key.
$results=array();
foreach($links as $link){
foreach($link as $value){
$results[$value] = isset($results[$value]) ? $results[$value]+1 : 1;
}
}
with your example data, your results would look like -
Array (
[1] => 5
[2] => 5
[3] => 5
[4] => 5
[5] => 5
[6] => 5
[7] => 2
[8] => 2
[9] => 1
[10] => 1
[11] => 1
)

Multi Array Prep for Charting

I searched for answers and could not find one. This is long and complex and looking for someone smart than me to answer.
Here is the situation. Using PHP, SQL, and trying Pchart.
1) Please do not suggest other charting tools. That is a waste of your time and mine. Other charting tool offer JAVA, JAVASCRIPT, JQUERY, and more. They are slick but what I need is simple (server side creation of data created dynamically and rendered using something on server. Why put the load on client side - at least for now while I investigate.
2) This is PHP specific question not the pchart tool.
Here is the scenario.
I have a table with results from swimming.
I can get the data formatted the way I need.
See below prints.
Array (assume this is first array)
(
[0] => Freestyle 50
[1] => Freestyle 100
[2] => Backstroke 50
[3] => Butterfly 50
[4] => Medley 100
)
Array (assume this is second array)
(
[Backstroke 50] => Array
(
[2012-11-04] => 51.08
[2012-11-10] => 52.50
[2012-11-25] => 55.48
[2012-12-01] => 47.56
[2012-12-08] => 44.51
[2012-12-15] => 49.46
[2013-01-19] => 47.12
[2013-11-03] => 42.52
[2013-11-09] => 40.94
[2013-11-10] => 42.97
[2013-11-16] => 41.36
[2013-12-01] => 45.16
[2013-12-08] => 40.59
[2014-01-12] => 37.67
[2014-02-01] => 37.70
)
[Freestyle 50] => Array
(
[2012-11-04] => 45.33
[2012-11-25] => 50.12
[2013-11-03] => 37.01
[2013-11-10] => 36.73
[2013-12-01] => 39.94
[2014-01-04] => 39.77
[2014-01-12] => 34.22
[2014-02-01] => 34.93
)
[Freestyle 100] => Array
(
[2012-11-04] => 137.73
[2012-11-10] => 126.86
[2012-12-08] => 133.65
[2013-11-03] => 124.14
[2013-11-10] => 121.94
[2013-11-16] => 121.10
[2013-12-01] => 130.99
[2013-12-07] => 118.27
[2013-12-08] => 122.44
[2014-01-04] => 131.38
[2014-01-11] => 115.95
[2014-01-18] => 120.06
)
[Medley 100] => Array
(
[2012-12-01] => 146.66
[2013-01-19] => 143.88
[2013-11-03] => 137.37
[2013-11-09] => 133.05
[2013-11-10] => 134.69
[2013-12-01] => 145.29
[2013-12-07] => 130.15
[2013-12-08] => 130.92
[2014-01-12] => 129.33
[2014-01-18] => 130.81
[2014-02-01] => 128.57
)
[Butterfly 50] => Array
(
[2013-12-08] => 46.82
[2014-01-12] => 43.66
)
)
Array (assume this is third array)
(
[2] => 2012-11-04
[14] => 2012-11-10
[1] => 2012-11-25
[31] => 2012-12-01
[15] => 2012-12-08
[26] => 2012-12-15
[24] => 2013-01-19
[7] => 2013-11-03
[28] => 2013-11-09
[4] => 2013-11-10
[11] => 2013-11-16
[3] => 2013-12-01
[9] => 2013-12-07
[12] => 2013-12-08
[5] => 2014-01-04
[10] => 2014-01-11
[0] => 2014-01-12
[13] => 2014-01-18
[6] => 2014-02-01
)
To line up the charting tool I need to have it in a string like this.
============== Backstroke 50 =================
51.08,52.50,55.48,47.56,44.51,49.46,47.12,42.52,40.94,42.97,41.36,45.16,40.59,37.67,37.70Create or Render Chart
"2012-11-04","2012-11-10","2012-11-25","2012-12-01","2012-12-08","2012-12-15","2013-01-19","2013-11-03","2013-11-09","2013-11-10","2013-11-16","2013-12-01","2013-12-08","2014-01-12","2014-02-01"
============== Freestyle 50 =================
45.33,50.12,37.01,36.73,39.94,39.77,34.22,34.93
"2012-11-04","2012-11-25","2013-11-03","2013-11-10","2013-12-01","2014-01-04","2014-01-12","2014-02-01"
============== Freestyle 100 =================
137.73,126.86,133.65,124.14,121.94,121.10,130.99,118.27,122.44,131.38,115.95,120.06
"2012-11-04","2012-11-10","2012-12-08","2013-11-03","2013-11-10","2013-11-16","2013-12-01","2013-12-07","2013-12-08","2014-01-04","2014-01-11","2014-01-18"
============== Medley 100 =================
146.66,143.88,137.37,133.05,134.69,145.29,130.15,130.92,129.33,130.81,128.57
"2012-12-01","2013-01-19","2013-11-03","2013-11-09","2013-11-10","2013-12-01","2013-12-07","2013-12-08","2014-01-12","2014-01-18","2014-02-01"
============== Butterfly 50 =================
46.82,43.66
"2013-12-08","2014-01-12"
What I am trying to achieve is to get the array #3 assumed. To be inserted in all of these list above. Example: butterfly has two dates. But I want to show all dates, and insert void times for the dates. This will allow the line getting rendered on the chart to be full use of the dates being displayed.
Here is the code:
First Array: Plus third array below this while:
while($result->fetchInto($data,DB_FETCHMODE_ASSOC)) {
$count ++;
$stroke = $data['stroke'];
$distance = $data['distance'];
$start = mysql2date($data['start']);
$dateARR[] = $data['start'];
$stroke = trim($c->getStrokeName($stroke));
$strokestr = $stroke . " " . $distance;
if($strokestr != $lastEvent) {
$strokeARR[] = $strokestr;
$lastEvent = $strokestr;
}
$lastEvent = $strokestr;
}
$dateARR = array_unique($dateARR);
asort($dateARR);
Second Array:
while($result->fetchInto($data,DB_FETCHMODE_ASSOC)) {
$stroke = $data['stroke'];
$distance = $data['distance'];
$start = mysql2date($data['start']);
$time = $c->integer2time($data['time']);
$time = str_replace(':', '', $time);
$meet = $data['meet'];
$stroke = trim($c->getStrokeName($stroke));
$strokestr = $stroke . " " . $distance;
$timeARR[$strokestr][$data['start']] = $time;
$count ++;
}
Should or how to make use of the while loop two in the second array and insert missing dates. Should I prefill the dates then compare during the loop to place the time or the VOID of time while building timeARR?
Any ideas out there?
Figured it out now.
// Loop through Stroke and add all dates.
foreach ($strokeARR as $key1 => $val1) {
print "$key1 = $val1\n";
foreach ($dateARR as $key2 => $val2) {
print "$key2 = $val2\n";
$TestARR[$val1][$val2] = "VOID";
}
}
I had to loop through and prefill with full date range then pre fill with VOID.
When I enter the second while loop I end up inserting time where needed. worked out. I wish I can do this in one pass but I am not that good.

Categories