Page 1 of 1

Eval and Multidimensional arrays - wont output the value

Posted: Fri Dec 15, 2006 10:18 pm
by s0me0ne
I am building a subnav and I cant get eval to echo out the value.

I can get the following to work:

Code: Select all

eval("return \$subnav_array;")
However if I do

Code: Select all

echo '<strong>' . eval("return \$subnav_array[0][0];") . '</strong>';
all I get is:

Code: Select all

<strong></strong>

Here is a bigger snippet of my code

Code: Select all

if ($nav_array[$row][2] != '')
	{
		$subnav_array = "$".$nav_array[$row][2];//get the name of the subnav array
		$num_in_subnav = eval("return count($subnav_array);");
		
		echo '<strong>'.$num_in_subnav.'</strong><br />';//DEBUG
		echo 'subnav array name= <strong>' .eval("return \$subnav_array;") . '</strong>';//DEBUG
		echo '<strong>' . eval("return \$subnav_array[0][0];") . '</strong>';//DEBUG
		
		echo '<ul>';
				
		for ($subrow = 0; $subrow < $num_in_subnav; $subrow++)
		{
			echo '<li><a href="' . eval("return \$subnav_array[$subrow][0];") . '">' . eval("return \$subnav_array[$subrow][1];") . '</a></li>';
		}
		
		echo '</ul>';
	}
I cant see why this isnt working :cry:

Posted: Fri Dec 15, 2006 10:23 pm
by John Cartwright
why are you using eval() all over the place... :?

Things like

Code: Select all

$num_in_subnav = eval("return count($subnav_array);");
can simply be done as

Code: Select all

$num_in_subnav = count($subnav_array);

Posted: Fri Dec 15, 2006 10:23 pm
by Kieran Huggins
First of all, eval() is evil.

Second of all, why are you storing the name of an array when you could just be storing the actual array?

If you referenced the array you might not even have to change much code...

Cheers,
Kieran

Posted: Sat Dec 16, 2006 12:26 am
by s0me0ne
because my arrays look like this


$nav_array = array(
array('home.php', 'Home', ''),
array('design.php', 'Design', 'subnav_design'),
...


$subnav_design = array(
array('web_design.php', 'Web Design'),
array('graphic_design.php', 'Graphic Design'),
array('product_design.php', 'Product Design'),
...

And so I put in the name of the subnav array in the nav array, I didnt know any other way to do a good nav, I dont have database access

Posted: Sat Dec 16, 2006 2:32 am
by Kieran Huggins
ok - try this:

Code: Select all

$nav_array = array(
	array('page'=>'home.php', 'name'=>'Home'),
	array('page'=>'design.php', 'name'=>'Design', 'menu'=>&$subnav_design),
	array('page'=>'other_stuff.php', 'name'=>'Other Stuff')
);

$subnav_design = array(
	array('page'=>'web_design.php', 'name'=>'Web Design'),
	array('page'=>'graphic_design.php', 'name'=>'Graphic Design'),
	array('page'=>'product_design.php', 'name'=>'Product Design')
);
I've made two notable changes: I made your arrays associative so the order of the elements doesn't matter, and I've added the $subnav array to the $nav array by association.

You don't need to do that, in fact you could just have it all in one giant array, but this method will require less re-writing on your part.

Now when you want to print your menu you can do something like:

Code: Select all

function makeMenu($array){
	$output="<ul>";
	foreach($array as $section){
		$output.='<li><a href="'.$section['page'].'">'.$section['name'].'</a>';
		if(@is_array($section['menu'])) $output.=makeMenu($section['menu']); // this line makes the function recursive - learn about them!
		$output.='</li>';
	}
	$output.="</ul>";
	return $output;
}

echo makeMenu($nav_array);
And you'll get a nested unordered list like this:

Code: Select all

* Home
    * Design
          o Web Design
          o Graphic Design
          o Product Design
    * Other Stuff
Best of all? No yucky eval() statements.

The @ sign in front of the is_array() function 'quiets' the function, which will otherwise moan and complain if the subnav array doesn't exist. There are many ways around this, and it's sort of bad practice, but I don't care that much in this case.

Cheers,
Kieran