Eval and Multidimensional arrays - wont output the value

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
s0me0ne
Forum Newbie
Posts: 3
Joined: Fri Dec 15, 2006 10:14 pm

Eval and Multidimensional arrays - wont output the value

Post 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:
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Post 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);
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post 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
s0me0ne
Forum Newbie
Posts: 3
Joined: Fri Dec 15, 2006 10:14 pm

Post 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
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post 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
Post Reply