PHP: Unexpected behavior: foreach... {$array['country'][] = $value['country']} - php

Why does the operator
$array['country'][] return what logically would be $array[]['country']?
What I am saying is this. If you want to extract from a MySQL array, the value of ['country'] for every row, [1],[2]...[n], you have to use
$array['country'][]
despite fact that they are ordered as
$array['row#']['country']
Is this because PHP is reading something backwards, or because I am just lacking some fundamental array information?
FULL-ish code here
$result = array();
foreach($data as $value){
$array['country'][] = $value['country'];
$array['report'][] = $value['report'];
}
$data = $array;
Let me know if I am just dumb... I can't really grasp why this is working this way.

get an id from the db
SELECT id,country,report from yourdb
while ($row = mysql_fetch_array($result)) {
$array['country'][$row['id']] = $row['country'];
$array['report'][$row['id']] = $row['report'];
}
create an id
SELECT country,report from yourdb
$i=0
while ($row = mysql_fetch_array($result)) {
$array['country'][$i] = $row['country'];
$array['report'][$i] = $row['report'];
$i++
}

Why does the operator
$array['country'][]
return what
logically would be
$array[]['country']?
It is because you are constructing the array in that way:
If you use $array['country'][] = $value['country'];, you are adding a new value to the sub-array which is part of the containing array under the country key. So it will be mapped to $array['country'][], you cannot expect otherwise.
If you want it to map to array[]['country'], then (using part of code from
#Lawrence's answer), you'd have to add the new values using explicit numerical indexes as the key:
SELECT country,report from yourdb
$i=0;
while ($row = mysql_fetch_array($result)) {
$array[$i]['country'][] = $row['country'];
$array[$i]['report'][] = $row['report'];
$i++;
}

Assuming that $data has been built by you using a loop like what you pasted in the comments (while($row=mysql_fetch_assoc($result)){$data[]=$row;}) then my answer would be because that's exactly what you asked PHP to do.
The notion $data[] = some-value-here means take that value and add it with to the end of $data array with an auto-generated key I just don't care. That is, PHP will basically see what the last item's key is, add 1 and use that as the key for the item you are adding to the array.
So what you are doing with that loop is building an array whose keys are numbers starting from 0 and incrementing (+1 each cycle, this is the [] effect) and using these keys for the rows you are getting off the database result set.
If you want to access $data in the way you described, then you have to change the way you are building it. See Lawrence Cherone's answer for that.

Related

How to find out automatically the numeric index of an specific MySQL column in PHP?

I´m new to PHP and SQL and it´s the first time I post here, hope I do it right =)
I need to find out the numeric index from an certain field in my database. Thing is I´m not done with the database structure yet, so for this specific field I´d like to have it automated so I won't have to change the code every time I add or remove columns.
I also need it to have BOTH index types so I can call the columns by name in part of the code and by index for automated parts of it.
I´ve managed to achieve the result I wanted trough an very ugly code, because all the array_search and array_keys I´ve tried didn´t work out for some reason.
Here is the snippet of my working but ugly code. Do you have an more elegant solution?
Thanks in advance for your answers, and for all I´ve learned so far from reading other peoples questions!
$dadosRes = mysqli_query($con, "SELECT * FROM Alunos WHERE Id=1");
$student = mysqli_fetch_array($dadosRes) or die(mysql_error());
$c = 0; // This block is to find out where the column "cont1" is and assign it to $cont1
$d=array_keys($student);
$cont1=0;
foreach ($student as $a=>$b){
if ($a==='cont1') {
$cont1=$d[$c-1];
}
$c++;
}
for ($i=$cont1; $i<$cont1+12; $i+=3) { // Displays the students contacts, each in up to 3 rows
if ($student[$i]) {
echo "<p><ul><li>".$student[$i]."</li>";
if ($student[$i+1]) echo "<li>".$students[$i+1]."</li>";
if ($student[$i+2]) echo "<li>".$students[$i+2]."</li>";
echo "</ul></p>";
}
}
Finding the numeric index:
$student = mysqli_fetch_array($dadosRes,MYSQLI_ASSOC) or die(mysql_error());
$numericIndex = array_search("cont1",array_keys($student));
Giving MYSQLI_ASSOC will force the query to fetch only the associative keys; otherwise it will give you both numeric and associative array.
PHP function, array_search in this case, requires the third parameter set to TRUE:
<?php
$dadosRes = mysqli_query($con, "SELECT * FROM Alunos WHERE Id=1");
$student = mysqli_fetch_array($dadosRes, MYSQLI_BOTH) or die(mysql_error());
$student_keys = array_keys($student);
$cont1 = $student_keys[array_search("cont1", $student_keys, true) - 1];
for ($i=$cont1; $i<$cont1+12; $i+=3) { // Displays the students contacts, each in up to 3 rows
if ($student[$i]) {
echo "<p><ul><li>".$student[$i]."</li>";
if ($student[$i+1]) echo "<li>".$student[$i+1]."</li>";
if ($student[$i+2]) echo "<li>".$student[$i+2]."</li>";
echo "</ul></p>";
}
}
?>
MYSQLI_BOTH is used in the mysqli_fetch_array function because first the array is searched for the column name, then later the array is looped over with numeric indexes. This results in the $student array having integer 0 as the first element and therefore causing array_search to choke. Adding true as the third parameter causes a === comparison unchoking the function. :) (Explanation: PHP array_search consistently returns first key of array )

How do I insert values into an multidimensional-array, then show them?

I'm fairly new to php, and I don't know how to work with arrays very well. Here's the deal, I want to add into a multidimensional array three or more values I obtain from my database, then I want to sort them based on the timestamp (one of the values). After that, I want to show all of the sorted values. I can't seem to do this, here's the code
$queryWaitingPatients = 'SELECT ArrivalTime, TargetTime, Order, Classification FROM exams WHERE (CurrentState = "Pending")';
$results = mysql_query($queryWaitingPatients) or die(mysql_error());
if (mysql_num_rows($results) == 0) {
echo '<p>There\'s currently no patient on the waiting list.</p>';
return;
}
while ($rows = mysql_fetch_array($results)) {
extract($rows);
//now is the part that I don't know, putting the values into an array
}
// I'm also not sure how to sort this according to my $TargetTime
asort($sortedTimes);
//the other part I don't know, showing the values,
Thanks for the help!
Well, let's look at your code. First, you have a query that's returning a result set. I don't recommend using mysql_fetch_array because it's not only deprecated (use mysqli functions instead) but it tends to lend itself to bad code. It's hard to figure out what you're referencing when all your keys are numbers. So I recommend mysqli_fetch_assoc (be sure you're fully switched to the mysqli functions first, like mysql_connect and mysqli_query)
Second, I really dislike using extract. We need to work with the array directly. Here's how we do this
$myarray = array();
while ($rows = mysqlI_fetch_assoc($results)) {
$myarray[] = $rows;
}
echo $myarray[0]['ArrivalTime'];
So let's go over this. First, we're building an array of arrays. So we initialize our overall array. Then we want to push the rows onto this array. That's what $myarray[] does. Finally, the array we're pushing is associative, meaning all the keys of the row match up with the field names of your query.
Now, the sorting really needs to be done in your query. So let's tweak your query
$queryWaitingPatients = 'SELECT ArrivalTime, TargetTime, `Order`, Classification
FROM exams
WHERE CurrentState = "Pending"
ORDER BY TargetTime';
This way, when your PHP runs, your database now churns them out in the correct order for your array. No sorting code needed.
$arr = array();
while ($rows = mysql_fetch_array($results)) {
array_push ($arr, $row);
}
print_r($arr);
<?php
$queryWaitingPatients = ' SELECT ArrivalTime, TargetTime, Order, Classification, CurrentState
FROM exams
WHERE CurrentState = "Pending"
ORDER BY TargetTime ';
$results = mysql_query($queryWaitingPatients) or die(mysql_error());
if ($results -> num_rows < 1)
{
echo '<p>There\'s currently no patient on the waiting list.</p>';
}
else
{
while ($rows = mysqli_fetch_array($results))
{
$arrivaltime = $row['ArrivalTime'];
$targettime = $row['targettime'];
$order = $row['Order'];
$classification = $row['Classification'];
echo "Arrival: ".$arrivaltime."--Target time: ".$targettime."--Order: ".$order."--Classification: ".$classification;
}
}
echo "Done!";
//or you could put it in a json array and pass it to client side.
?>

PHP multidimensional array from database results

I'm a bit new to multidimensional arrays, and would like to see if I'm doing it right. preferably, I'd like to name the arrays within the main array for ease of use.
$unique_array = array(
username=>array(),
user_id=>array(),
weeknumber=>array()
);
and then I have a while loop which checks some database results:
while($row = mysql_fetch_array($query)) //yes, I know mysql is deprecated
{
$unique_array[] = username=>$row['username'], user_id=>$row['user_id'], week number=>['weeknumber'];
}
I'm not sure if I am placing the values in the array from within the while loop correctly, or if it needs to be done some other way. I couldn't find any resources I could easily understand on SO or elsewhere to deal with query results within a named array within a multidimensional array.
EDIT FOLLOW UP QUESTION: I also need to check the array for duplicate values, because there will be multiple values that are exactly the same, but I only want one of them.
Any help is appreciated!
EDIT SOLUTION:
By modifying the answer I was able to create code to fit my needs.
Array initialization:
$unique_array = array(
'username'=>array(),
'user_id'=>array(),
'weeknumber'=>array()
);
Building the array from within a while loop:
while($row = mysql_fetch_array($query))
{
$unique_array[] = array('username'=>$row['username'], 'user_id'=>$row['user_id'], 'weeknumber'=>$row['weeknumber']);
}
And finally, I need to make sure the array values are unique (there are duplicates entries as a result of database and query limitations), after the while loop I have:
print_r(multi_unique($unique_array));
Is the top level an associative array or a numeric array?
If it is an associative array, it should have structure like this:
$unique_array = array(
'username'=>array('John','Mike',...),
'user_id'=>array(1,2,3,...),
'week_number'=>array(1,2,3,...)
);
Or if it is a numeric array, it should have structure like this:
$unique_array = array(
array('username'=>'John', 'user_id'=>1, 'week_number'=>1),
array('username'=>'Mike', 'user_id'=>2, 'week_number'=>2),
array('username'=>'Sam', 'user_id'=>3, 'week_number'=>3),
...
)
for the first type use the code below:
while ($row = mysql_fetch_assoc($query)) {
$unique_array['username'][] = $row['username'],
$unique_array['user_id'][] = $row['user_id'],
$unique_array['week_number'][] = $row['week_number'],
}
for the second type, it is something like your code. But there are some syntax problems:
while($row = mysql_fetch_array($query)) //yes, I know mysql is deprecated
{
$unique_array[] = array('username'=>$row['username'], 'user_id'=>$row['user_id'], 'week_number'=>$row['weeknumber']);
}

while loop into in array

What am I trying to do is collect data from a while loop, store it into a variable. Then later in my code I see if some variable is equal to one of the values in the array and then to echo out the two other column values I got from the while loop but equal to the row that the value came from. I have tried a bunch different things and am so close but cant get it exactly.
while($row = mysql_fetch_assoc($query)){
$team[] .= "{$row['team']}";
$winslosses .= "({$row['wins']} - {$row['losses']})";
}
this returns something like
$team = (bears, badgers, wildcats)
$winslosses = ((42-24), (55-23), (32-21))
Then later in my code I want to see if its equal to a value in the array then echo $winslosses.
if(in_array(bears, $team) ) {echo '$winslosses';}
This shows all the wins and losses from each team. I want it only show me the record of the bears.
Any help would be great.
You can use array_search() to get the index of an item in an array. You can then use that index when querying $winlosses:
$team = array(bears, badgers, wildcats);
$winslosses = array("(42-24)", "(55-23)", "(32-21)");
$key=array_search(bears, $team);
echo $winslosses[$key]
results in:
(42-24)
Your best bet would be to store them in an associative array.
while($row = mysql_fetch_assoc($query)){
$winslosses[$row['team']] = "({$row['wins']} - {$row['losses']})";
}
Hope this helps
Your main problem is that you currently have $winslosses as a string, not an array, so you can't easily pull out the win/loss record for just one team.
There are several ways you could do this. The one that seems easiest to me would be to put it together as one array up front.
Something like...
while($row = mysql_fetch_assoc($query)){
$teams[$row['team']] = "({$row['wins']} - {$row['losses']})";
}
Then later on...
if(array_key_exists("bears",$teams)) {
echo $teams["bears"];
}
Or even better, store the wins/losses as a sub-array, so you have structured data that you can format however you want later on.
while($row = mysql_fetch_assoc($query)){
$teams[$row['team']] = array("wins" => $row['wins'], "losses" => $row['losses']);
}
echo $teams['bears']['wins']; // for example
Use associative array:
while($row = mysql_fetch_assoc($query)){
$team[] = {$row['team']};
$winslosses[$row['team']] = "{$row['wins']} - {$row['losses']}";
}
Then retrieve it like this:
if(in_array(bears, $team) ) {
echo $winslosses['bears'];
}
As a matter of fact, if you do not need the names of the teams in a separate array, you can just use one associative array and then retrieve it.
if (array_key_exists('bears', $winslosses)) {
echo $winslosses['bears'];
}

making three dimensional array that has an unknown amount of arrays inside

I'm trying to store data from a table, and I do not know how many lines will be in said table. My idea was to make a main array called data, a sub array for each line with just numeric labels (1,2,3,etc) and then inside each of those would be the actual data from each line, so it would be like this:
data
->1
->item1
->item2
->item3
->2
->item1
->item2
->item3
->3
->item1
->item2
->item3
ETC. I know how to work with multidimensional arrays and I know there are easy ways to accomplish this in java, but I can't for the life of me figure out how to do it in php.
To keep on adding to an array simply use the following code:
$myArray[] = 'another value';
Notice the [] this tells php to add another value to the array (without removing previous elements)
See here for a quick tutorial on mutidimensional arrays:
http://webcheatsheet.com/PHP/multidimensional_arrays.php
And this:
http://www.developerdrive.com/2012/01/php-arrays-array-functions-and-multidimensional-arrays/
Try,
foreach($rows as $v) {
$data[] = array($v['item1'], $v['item2'], $v['item3']);
}
To map mySQL data to a multidimensional array:
$query = mysql_query("SELECT * FROM table WHERE uid = '1' ORDER BY id DESC");
$results = array();
$i = 0;
while($line = mysqli_fetch_array($query, MYSQL_ASSOC)){
$results[$i] = $line;
$i++;
}

Categories