foreach loop corrupting my array? - php

Explanation
I have a multidimensional array that is iterated over to created a categorized view of people with different research interests. The main array look something like this:
Array
(
...
['Cell Biology'] => Array(4 elements)
['Molecular'] => Array(6 elements)
['Biology Education'] => Array(14 elements)
['Plant Biology'] => Array(19 elements) <--- Last element in array
)
I know that the entire array is intact and correctly structured. The only information that is inside these array is an user id, like so:
Array ('Plant Biology') 19 elements
(
[0] => 737
[1] => 742
[2] => 748
...
)
My problem is that after i run the main array through a foreach loop the last 'sub-array' gets messed up. By messed up I mean that what you see about instead look like:
String (13 characters) 'Plant Biology'
This is without doing at all anything inside the loop with to the array that gets corrupted.
Any tips to what it might be?
PHP Code
// ---> Array is OK here
echo "<h2>Research divided</h2>";
// Loop areas and list them in 2 columns
foreach($research['areas'] as $area => $areaArray) {
// ---> Here it is already corrupted
$count = count($areaArray);
if($count > 0) {
echo "<h3>$area</h3><hr/>";
echo "<ul>";
// Loop users within areas, divided up in 2 columns
for($i=0 ; $i<$count ; $i++) {
$uid = $areaArray[$i];
echo "<li>$uid</li>";
}
echo "</ul>";
}
}

Are $area or $areaArray being used in different function elsewhere in your script? Wht happens if you rename them to $loop_area and $loop_areaArray to prevent accidental overwriting of variables?

It looks like an error that can occur if you loop over the array previously by referance using the same variable name for the value.
So if earlier in your code $areaArray is used in a foreach by referance it might corrupt your data.
Make sure both variables in your foreach are not used previously or unset them before the loop.
Check out:
http://bugs.php.net/29992
For more info on this kind of problem.

Related

increment value inside an array of arrays (if key is non-existent, set it to 1)

Question has been updated to clarify
For simple arrays, I find it convenient to use $arr[$key]++ to either populate a new element or increment an existing element. For example, counting the number of fruits, $arr['apple']++ will create the array element $arr('apple'=>1) the first time "apple" is encountered. Subsequent iterations will merely increment the value for "apple". There is no need to add code to check to see if the key "apple" already exists.
I am populating an array of arrays, and want to achieve a similar "one-liner" as in the example above in an element of the nested array.
$stats is the array. Each element in $stats is another array with 2 keys ("name" and "count")
I want to be able to push an array into $stats - if the key already exists, merely increment the "count" value. If it doesn't exist, create a new element array and set the count to 1. And doing this in one line, just like the example above for a simple array.
In code, this would look something like (but does not work):
$stats[$key] = array('name'=>$name,'count'=>++);
or
$stats[$key] = array('name'=>$name,++);
Looking for ideas on how to achieve this without the need to check if the element already exists.
Background:
I am cycling through an array of objects, looking at the "data" element in each one. Here is a snip from the array:
[1] => stdClass Object
(
[to] => stdClass Object
(
[data] => Array
(
[0] => stdClass Object
(
[name] => foobar
[id] => 1234
)
)
)
I would like to count the occurrences of "id" and correlate it to "name". ("id" and "name" are unique combinations - ex. name="foobar" will always have an id=1234)
i.e.
id name count
1234 foobar 55
6789 raboof 99
I'm using an array of arrays at the moment, $stats, to capture the information (I am def. open to other implementations. I looked into array_unique but my original data is deep inside arrays & objects).
The first time I encounter "id" (ex. 1234), I'll create a new array in $stats, and set the count to 1. For subsequent hits (ex: id=1234), I just want to increment count.
For one dimensional arrays, $arr[$obj->id]++ works fine, but I can't figure out how to push/increment for array of arrays. How can I push/increment in one line for multi-dimensional arrays?
Thanks in advance.
$stats = array();
foreach ($dataArray as $element) {
$obj = $element->to->data[0];
// this next line does not meet my needs, it's just to demonstrate the structure of the array
$stats[$obj->id] = array('name'=>$obj->name,'count'=>1);
// this next line obviously does not work, it's what I need to get working
$stats[$obj->id] = array('name'=>$obj->name,'count'=>++);
}
Try checking to see if your array has that value populated, if it's populated then build on that value, otherwise set a default value.
$stats = array();
foreach ($dataArray as $element) {
$obj = $element->to->data[0];
if (!isset($stats[$obj->id])) { // conditionally create array
$stats[$obj->id] = array('name'=>$obj->name,'count'=> 0);
}
$stats[$obj->id]['count']++; // increment count
}
$obj = $element->to->data is again an array. If I understand your question correctly, you would want to loop through $element->to->data as well. So your code now becomes:
$stats = array();
foreach ($dataArray as $element) {
$toArray = $element->to->data[0];
foreach($toArray as $toElement) {
// check if the key was already created or not
if(isset($stats[$toElement->id])) {
$stats[$toElement->id]['count']++;
}
else {
$stats[$toElement->id] = array('name'=>$toArray->name,'count'=>1);
}
}
}
Update:
Considering performance benchmarks, isset() is lot more faster than array_key_exists (but it returns false even if the value is null! In that case consider using isset() || array_key exists() together.
Reference: http://php.net/manual/en/function.array-key-exists.php#107786

Array ( [0] => Array ... problems extracting array values

I am trying to run a function that gets information from a DB and returns an array of the values, so I can then extract it on the page.
Inside the function, after my query I have the following code:
$example_array = array();
while ($row = mysql_fetch_assoc($query) {
$example_array[] = $row;
}
return $example_array;
And there ends my function. Outside of it, I have this:
extract($example_array);
And I would assume I could then directly echo any of the variables that were previously in $example_array, e.g. <?= $example_var ?> but they do not contain any data.
Running print_r($example_array); gives an array that looks like this:
Array ( [0] => Array ( [example_var] => Example String ) )
The start of that code makes me think my array is somehow "lost" inside another array's first ([0]) value, and as such is not extracting correctly.
Have I gone about adding data to that initial $example_array incorrectly?
When you do $example_array[] = $row;, you assign the current row to a new index of $example_array. If you want to access it like $example_array['row_name'], you'd have to assign it like this:
$example_array = $row;
But when you do this, $example_array will be overwritten until it has reached the last row (which means that $example_array will always contain the last row from the query). If you just want the first row, you can do this and skip the whole while loop:
$example_array = mysql_fetch_assoc($query);
Maybe :
$example_array = array();
while ($row = mysql_fetch_assoc($query) {
array_push($example_array, $row['exemple_var']);
}
return $example_array;
The issue is that mysql_fetch_array would have meant $row['row_name'] was valid.
As you added $row to the array $example_array, you now need to access it via it's array id too, such as;
$example_array[0]['row_name'], $example_array[1]['row_name'] etc.
What exactly are you trying to achieve? May be easier to offer assistance if we know.

Breaking a MultiDimensional Array into a Single Dimension

I have fields in mySQL which is currently being stored like this under the field "tags"
Shopping|Health & Beauty
Coffee|Shopping
What I'm trying to do is to loop through this to create a single dimension array and to grab only the unique values.
I have my query selecting DISTINCT tags from TABLE and run the loop like this:
while ($row_tags = mysql_fetch_assoc($r_tags)) {
$tags = $row_tags['tags'];
$imploded_tags[] = explode("|",$tags);
}
echo "<pre>";
print_r($imploded_tags);
The result from the print_r is showing it as a multidimensional array. I've tried to reexplode it and implode it in different ways, but I haven't been able to get any success. Is there a way that I can create this into a single dimension array? Not all tags will have an equal amount of tags separated by |, so I can't seem to get it to go with a function that I tried from another StackOverflow post. Any help would be greatly appreciated!
OUTPUT:
Array
(
[0] => Array
(
[0] => Shopping
[1] => Health & Beauty
)
[1] => Array
(
[0] => Coffee
[1] => Shopping
)
try this
while ($row_tags = mysql_fetch_assoc($r_tags)) {
$tags = $row_tags['tags'];
$tags = explode("|",$tags);
foreach($tags as $v){
$imploded_tags[] = $v;
}
}
I would do something like:
$imploded_tags = array_merge(explode("|",$tags), $imploded_tags);
}
$imploded_tags = array_unique($imploded_tags);
echo "<pre>";
print_r($imploded_tags);
See the manual on array_merge and array_unique.
However, I do think you are not using the right way to store your tags; they should be stored in a separate table as separate values.
What's going on is when you're fetching your rows from MySQL, you're essentially getting a bunch of data in an array in the first place, which is why you have to loop through them.
With your your implode function, you're taking a bunch of strings, then getting another array set and then appending that to an external array.
If you really wanted to get a single dimensional array without having this multidimensional thing going on, all you really need to do is utilize another loop within that loop.
$all_tags = array();
while ($row_tags = mysql_fetch_assoc($r_tags)) {
$tags = $row_tags['tags'];
$imploded_tags[] = explode("|",$tags);
for($i = 0; $i < count($imploded_tags); $i++) {
$all_tags[] = $imploded_tags[$i]
}
}
print_r($all_tags);

PHP storing array column output from a function i call upon multiple times

I am trying to merge two parts of a code. To do that i have to store the echo'd array column output from a function which i call on
multiple times into an array or arrays on which I can perform computations.
Here's what i'm trying to do:
<?php
$searchquery[1] ="jupiter";
$searchquery[2] ="venus";
//can be multiple queries
include ('find.php');
for($i=0;$i<count($searchquery);$i++)
{
find($searchquery[$i]);
}
/find.php echoes back to me a MySQL query which then
creates a 2 dimensional array for me called
/$searchresult which looks like this as an example
t x (let's call first column t for example, and second x)
|1|3|
|1|4|
|2|6|
|4|8|
|7|1|
and it echoes it back to me, this works.
But, i need to use the first column (t) (11247) output from find.php
which was the result of the searchquery "jupiter",
and i need to store it as some sort of array in this current sheet,
theni need to store the "venus" searchquery which is let's say
t x
|1|3|
|2|4|
|3|4|
|4|6|
|5|4|
and store the first column (t) as an array in this current sheet.
I am trying to store the echos from the find.php function as arrays so that
i can perform the following operation in the current sheet:
$venusarrayt = array(1, 1, 2, 4, 7); //the manually defined
//$searchresult first column output from find.php which echos to me (t) (11247)
$jupiterarrayt = array(1, 2, 3,4,5); //the manually defined
//$searchresult first column output from find.php which echos to me (t) (12345)
//I need to perform the following operation and sum all of the t combinations
for($l=0;$l<count($venusarrayt);$l++){
for($s=0;$s<count($jupiterarrayt);$s++){
echo $venusarrayt[$l]+$jupiterarrayt[$s];
This part works! But i am having trouble though merging the echo'd $searchresult output into an array on which i can perform the above
for loops. In this example i am doing it by hand by typing into the php sheet "venusarrayt and jupiterarrayt".
I am sure there is some way to store echo'd array column results from a function which i call upon multiple times into an array, but i
haven't figured out yet how. Please help.
I hope this helps:
<?php
$searchquery[0] ="jupiter";
$searchquery[1] ="venus";
//can be multiple queries
include ('find.php');
$results=null;
for($i=0;$i<count($searchquery);$i++)
{
$temp=find($searchquery[$i]);
$results[$i]=$temp[t];
}
for($l=0;$l<count($results[1]);$l++){
for($s=0;$s<count($results[0]);$s++){
echo $results[1][$l]+$results[0][$s];
}
}
Clear solution for anyway of further working with your searched data can looks something like this:
$searchquery[1] ="jupiter";
$searchquery[2] ="venus";
$search_result = array(); $i=0;
foreach($searchquery as $current_query){
$current_result = FindResul($current_query);
// FindResult will be your function which process single query and returns result of it
$search_result[$i]['query'] = $current_query;
$search_result[$i]['result'] = $current_result;
$i++;
}
After the execution the code above you will have array 2-lvl array with clear and easy to work with structure. You can use it how you'd like to compare data or show it in the way you want.
Resulting array will have such structure:
$search_result[0]['query'] = 'jupiter';
$search_result[0]['result'] = '...jupiter resul';
$search_result[1]['query'] = 'venus';
$search_result[1]['result'] = '...venus result';
You have to create nested array to resolve the issue I would give a little example how to do?
$searchquery[1] ="jupiter";
$searchquery[2] ="venus";
for($i=1;$i<=count($searchquery);$i++){
$temp=find($searchquery[$i]);
$results[$i]=$temp[t];
}
$k=$i;
for($z=0;$z<=$i;$z++){
$total='';
for($p=0;$p<=$k;$p++){
$total=$total+$results[$p][$z];
}
echo $total;
echo "\n";
}
function find($word){
return array('t' => array('1', '2', '4', '7'));
}
and answer would be something like this:
Array
(
[1] => Array
(
[0] => 1
[1] => 2
[2] => 4
[3] => 7
)
[2] => Array
(
[0] => 1
[1] => 2
[2] => 4
[3] => 7
)
)
2
4
8
14
This solution will add all the n number of queries first result, second result and so on.......

How to search array for duplicates using a single array?

I am checking a list of 10 spots, each spot w/ 3 top users to see if a user is in an array before echoing and storing.
foreach($top_10['top_10'] as $top10) //loop each spot
{
$getuser = ltrim($top10['url'], " users/" ); //strip url
if ($usercount < 3) {
if ((array_search($getuser, $array) !== true)) {
echo $getuser;
$array[$c++] = $getuser;
}
else {
echo "duplicate <br /><br />";
}
}
}
The problem I am having is that for every loop, it creates a multi-dimensional array for some reason which only allows array_search to search the current array and not all combined. I am wanting to store everything in the same $array. This is what I see after a print_r($array)
Array ( [0] => 120728 [1] => 205247 ) Array ( [0] => 232123 [1] => 091928 )
There seems to be more to this code. As there are variables being called in it that aren't defined, such as $c, $usercount, etc.. And using array_search with the 2nd parameter of $array if it doesn't exist is not a good idea also. Since it seems like $array is being set within the if statement for this only.
And you don't seem to be using the $top10 value within the foreach loop at all..., why is this?
It would help to see more of the code for me to be able to help you.

Categories