Jump to content

Array disappearing in foreach loop


Miker

Recommended Posts

Okay, I have this problem where an array will become undefined in a foreach loop.

 

Here is the function plus a couple comments:

function mineResources($nation) {
global $db;
$resources = $nation['resources'];

//Right here $resources would work

$sectors = $db->getSectorList($nation['id']);
foreach($sectors as $sector) {
//In here, $resources is empty
$sectorResources = $sector['resources'];
foreach($sectorResources as $key => $sResource) {
  //Does nothing because $resources is empty when it gets here.
  $resources[$key] += $sResource;
}
}
$db->updateCountryInfo($nation, array("resources" => $resources));
}

 

$db is a global array that holds database information. $nation is an array that holds a nation's data. All arrays work except for $resources and even $resources work outside of the foreach loops. Any ideas why this is happening?

Link to comment
Share on other sites

Hmm... interesting.

function mineResources($nation) {
global $db;
$resources = $nation['resources'];

$sectors = $db->getSectorList($nation['id']);
foreach($sectors as $sector) {
	$sectorResources = $sector['resources'];
	foreach($sectorResources as $key => $sResource) {
		echo "<BR>";
		print_r($resources);
		$resources[$key] += $sResource;
	}
}	
$db->updateCountryInfo($nation, array("resources" => $resources));
}

 

Produces:

Array ( [id] => 1 )
Array ( [id] => 1 [Crops] => 2 )
Array ( [id] => 1 [Crops] => 2 [Wood] => 0 )
Array ( [id] => 1 [Crops] => 2 [Wood] => 0 [Coal] => 0 )
Array ( [id] => 1 [Crops] => 2 [Wood] => 0 [Coal] => 0 [Petroleum] => 10 )
Array ( [id] => 1 [Crops] => 2 [Wood] => 0 [Coal] => 0 [Petroleum] => 10 [Aluminum] => 0 )
Array ( [id] => 1 [Crops] => 2 [Wood] => 0 [Coal] => 0 [Petroleum] => 10 [Aluminum] => 0 [iron] => 0 )
Array ( [id] => 1 [Crops] => 2 [Wood] => 0 [Coal] => 0 [Petroleum] => 10 [Aluminum] => 0 [iron] => 0 [Copper] => 0 )
Array ( [id] => 1 [Crops] => 2 [Wood] => 0 [Coal] => 0 [Petroleum] => 10 [Aluminum] => 0 [iron] => 0 [Copper] => 0 [Lead] => 0 )
Array ( [id] => 1 [Crops] => 2 [Wood] => 0 [Coal] => 0 [Petroleum] => 10 [Aluminum] => 0 [iron] => 0 [Copper] => 0 [Lead] => 0 [silver] => 0 )
Array ( [id] => 1 [Crops] => 2 [Wood] => 0 [Coal] => 0 [Petroleum] => 10 [Aluminum] => 0 [iron] => 0 [Copper] => 0 [Lead] => 0 [silver] => 0 [Gold] => 0 ) 

 

Using the print_r outside of the loop(right after $resources is first defined produces:

Array ( [id] => 2 [Crops] => 4 [Wood] => 1 [Coal] => 1 [Petroleum] => 1 [Aluminum] => 2 [iron] => 0 [Copper] => 0 [Lead] => 0 [silver] => 0 [Gold] => 0 [uranium] => 0 ) 

 

That is what it should be.

Link to comment
Share on other sites

variable $resources does NOT exist outside function!!

 

You are correct; $resources does not exist outside the function, but it does exist inside the function. For some reason, it does not appear to exist within the foreach loops which is where I need it to exist.

 

I must say that I have not seen anything like this and neither have any of my more skilled friends.

Link to comment
Share on other sites

I've found that if I declared the $resources as an array using array() to match exactly what $nation['resources'] looks like, it works.

 

Here's the code if you did not understand what I said:

function mineResources($nation) {
global $db;
//$resources = $nation['resources'];
$resources = array ( "id" => 2, "Crops" => 4, "Wood" => 1, "Coal" => 1, "Petroleum" => 1, "Aluminum" => 2, "Iron" => 0, "Copper" => 0, "Lead" => 0, "Silver" => 0, "Gold" => 0, "Uranium" => 0 );

$sectors = $db->getSectorList($nation['id']);
foreach($sectors as $sector) {
	$sectorResources = $sector['resources'];
	foreach($sectorResources as $key => $sResource) {

		print_r($resources);echo "<BR>";
		//$resources[$key] += $sResource;
	}
}	
//$db->updateCountryInfo($nation, array("resources" => $resources));
}

 

This works, but is not a solution to the problem because I need to set $resources to $nation['resources'];

Link to comment
Share on other sites

function mineResources($nation) {
global $db;
$resources = $nation['resources'];

$sectors = $db->getSectorList($nation['id']);
foreach($sectors as $sector) {
	$sectorResources = $sector['resources'];
	foreach($sectorResources as $key => $sResource) {
		//$resources[$key] += $sResource;
	}
}	
//$db->updateCountryInfo($nation, array("resources" => $resources));
}

 

$nation is an array. $nation['resources'] is an array. $db is an array. $db->getSectorList() returns an array $sectors. $sector['resources'] is an array. The only array that is still defined within the foreach loops is $sectors. The others are undefined within the loops, but before and after the loops, they work fine.

Link to comment
Share on other sites

Ok, so that code makes a couple of things a bit clearer.

 

The first thing i see is that your main assumptions are:

 

$sector['resources'] is an array.  That might be true but it might not.  There is no way for me to know or help you debug, because the answer is entirely dependent on what $db->getSectorList() does.

 

 

 

Secondly, I'm curious about $resources.  All you're doing is an assignment statement, so I would again want to know if $resources is an array immediately after you create it with the assignment of

 

$resources = $nation['resources'];

 

 

Here is one thing that you may have stumbled upon previously, and that's the use of print_r().  If you print_r an array you are moving the internal array pointer that is used by foreach().  So if you did that inside a foreach loop, you could have caused a side effect that caused you to become confused.  You can try the is_array() or you can reset() the array after the print_r.

 

Needless to say print_r is great for questioning assumptions, but at times it's a good idea to simply use die() after it, and then figure out one conundrum at a time. 

 

 

Link to comment
Share on other sites

Ok, so that code makes a couple of things a bit clearer.

 

The first thing i see is that your main assumptions are:

 

$sector['resources'] is an array.  That might be true but it might not.  There is no way for me to know or help you debug, because the answer is entirely dependent on what $db->getSectorList() does.

 

 

 

Secondly, I'm curious about $resources.  All you're doing is an assignment statement, so I would again want to know if $resources is an array immediately after you create it with the assignment of

 

$resources = $nation['resources'];

 

 

Here is one thing that you may have stumbled upon previously, and that's the use of print_r().  If you print_r an array you are moving the internal array pointer that is used by foreach().  So if you did that inside a foreach loop, you could have caused a side effect that caused you to become confused.  You can try the is_array() or you can reset() the array after the print_r.

 

Needless to say print_r is great for questioning assumptions, but at times it's a good idea to simply use die() after it, and then figure out one conundrum at a time.

 

$sector['resources'] is an array. It is loaded into $sector the same way the $nation['resources'] is loaded into $nation. Same function is called, actually. $db->getSectorList() just returns an array of $sector that have $nation['id'] as a certain value. There is no problem with $sector['resources'] or $sectors. They are functioning properly.

 

I am pretty sure $resources is an array after assignment from $nation['resources']. Using is_array() returns true and print_r() prints what it should look like. But then the foreach loop happens and is_array($resources) does not return at all.

 

I've found something interesting through experimentation. See mineResources() is called in loop of all nations. If I echo the name of the nation at $nation['name'], then it will display all the nations' names. However, if I place the echo inside the foreach loop, it will only display the name of the last nation, Testopolis. Only nation that should even go into the foreach loop is the second to last nation, Zeon, and that is because only Zeon has any sectors.

 

At the top of this, there is updates.php which does this:

global $db;

$nations = $db->getNationList();

foreach($nations as $nation) {
// Income report happens here
incomeReport($nation);
}

 

Here are the first few lines of incomeReport():

function incomeReport($nation) {
global $db;

// Mine Resources
mineResources($nation);

 

Could the foreach loop in updates.php be affecting the change in $resources and $nation?

Link to comment
Share on other sites

I really don't see anything obvious, but I also feel like I don't have the full picture.  When you have routines in play that are manipulating large nested arrays, and are populating these from queries, just a small mistake is certainly enough to throw your results off.  As I said earlier in the thread, I can only suggest you question your assumptions.    I also noted, that print_r will effect the results of arrays that you are stepping through in a loop.

 

I don't know if you have xdebug installed, but you might find it helps you out in exploring the problem further.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.