Jump to content


Photo

foreach in function in library returns invalid argument when called.


  • Please log in to reply
6 replies to this topic

#1 smashingred

smashingred
  • Members
  • PipPip
  • Member
  • 15 posts

Posted 18 September 2006 - 03:05 AM

I have been hacking away slowly at php as a fairly green noob. I have created a menu list using an array and foreach to build the meny which includes a conditional for the section of a website. I have decided to place turn all such sets into functions by creating a function library and calling the function but I am getting an "Invalid argument supplied for foreach(): error.

I tried using the "globals $foo" and '$GLOBALS ['foo']" but neither seemed to change the outcome. Here is the original code:

<?php 
	
//This array defines the links and the site_section names for the links list created by the foreach

$links = array(''=>'home','blog/'=>'blog','about/'=>'about','contact/'=>'contact');
	
// This foreach statement creates a menu with as many links as $values in the array and converts text to first letter uppercase
foreach($links as $key => $value){
		echo '<li';
		if ($site_section == $value)
		{ echo ' class="active"'; } 
		else { echo '';} echo '><a'; 
		if ($site_section == $value){ echo ' id="current"'; } 
		else { echo '';} echo ' href="'.SITE_TOP_PATH.$key.'">'.ucfirst($value).'</a></li>'."\n";}
		
?>

Here is the function library snippet:

<?php
function menu_display() {
		global $links, $site_section, $key, $value;
    
		foreach($links as $key => $value){
    		echo '<li';
    		if ($site_section == $value)
    		{ echo ' class="active"'; } 
    		else { echo '';} echo '><a'; 
    		if ($site_section == $value){ echo ' id="current"'; } 
    		else { echo '';} echo ' href="'.SITE_TOP_PATH.$key.'">'.ucfirst($value).'</a></li>'."\n";
				}
    }?>

Here is what the array file looks like with the function call:
<?php 
	
//This array defines the links and the site_section names for the links list created by the foreach

$links = array(''=>'home','blog/'=>'blog','about/'=>'about','contact/'=>'contact');
	
//This function generates the menu bar	
		menu_display();
?>

It is the last one that won't work in conjunciton with the called function. Wheras the first sample file works fine while the foreach is executed in the same file as the array $links.

Please let me know, a true noob, what I am doing wrong here to make this not work.

All the best,

Jay

#2 kenrbnsn

kenrbnsn
  • Staff Alumni
  • Advanced Member
  • 8,235 posts
  • LocationHillsborough, NJ, USA

Posted 18 September 2006 - 04:09 AM

Instead of using globals, pass the variables $links and $site_section to the function. You don't need $key & $value as globals or as passed variables, since they are local to the function:
<?php
$links = array(''=>'home','blog/'=>'blog','about/'=>'about','contact/'=>'contact');

functioin menu_display($links,$site_section) {
     foreach($links as $key=>$value) {
        $class = '';
        $id = '';
    	if ($site_section == $value) {
           $class = ' class="active"';
           $id = ' id="current"'; }
  	echo '<li' . $class . '><a' . $id . ' href="'.SITE_TOP_PATH.$key.'">'.ucfirst($value).'</a></li>'."\n";
     }
}
//
//
//   other code
//
//
menu_display($links,$site_section);
?>

I also tightened up your code.

Ken


#3 smashingred

smashingred
  • Members
  • PipPip
  • Member
  • 15 posts

Posted 18 September 2006 - 10:39 AM

Ken thanks for the code and the cleanup. I had read about passing variables in the function call in a couple of books but I really didn't understand the context for usage. I will have to look into this more.

ATB,

Jay

#4 smashingred

smashingred
  • Members
  • PipPip
  • Member
  • 15 posts

Posted 18 September 2006 - 11:36 AM

So the function now calls but the conditional no longer works. I don't know how to pass $site_section variable to the function as it comes from a file that calls all the includes.

Here is the scenario:

I have a php file that calls all the other code called index.php. It requires a file called page_start.inc.php that requires the function library--functions.php (and some other files--contstants and config files).

In functions.php I have functions that create the whole top section of the page, the main_menu and the other elements of the page.

On the index.php I create the variable "$site_section". Prior to my moving the above function to the functions.php file the variable was passed into the foreach loop without issue. Now that I have multiple functions calling and cascading is there something that I need to do to make sure that $site_section continues to pass to the function?

I have tried adding "$site_section" to the functions that are called as was done in the code above but it still doesn't work?

What am I missing??

#5 kenrbnsn

kenrbnsn
  • Staff Alumni
  • Advanced Member
  • 8,235 posts
  • LocationHillsborough, NJ, USA

Posted 18 September 2006 - 11:44 AM

Please post all of your code. Without it we can't help you.

Ken

#6 smashingred

smashingred
  • Members
  • PipPip
  • Member
  • 15 posts

Posted 18 September 2006 - 12:02 PM

Sorry Ken, Here Goes:

index.php
<?php
		REQUIRE $_SERVER['DOCUMENT_ROOT'].'/_sandbox/_includes/page_start.inc.php';
     
			//This is the site section that at the top level of this site.
			//It is used to control the state of navigation and breadcrumbs etc.
		 		$site_section = 'about';
			
			//Title to be displayed in the title bar of this page in the browser.
				$page_title = 'Page Title'. ': ';
     
			// Keywords to be displayed in the headers of this page.
				$page_keywords = '';
     
			// Description to be displayed in the headers of this page.
				$page_description = '';
     
			// Links Specific to this section of the site.
				$page_section_links = '';
			
			// Sets whether subcontent is shown or not.
				$omit_subcontent = false;  //true omits subcontent; false includes subcontent
		 
// Place The Page Top

		place_top($site_section);
			
# Place Content Below This #
?>

page_start.inc.php
<?php 
		// Get Main Config File
		REQUIRE $_SERVER['DOCUMENT_ROOT'].'/_sandbox/_includes/conf/config.inc.php';
		
    // Get Site Constants
    REQUIRE $_SERVER['DOCUMENT_ROOT'].'/_sandbox/_includes/lib/constants.php';
		
    // Get Function Library
    REQUIRE $_SERVER['DOCUMENT_ROOT'].'/_sandbox/_includes/lib/functions.php';
?>

functions.php
<?php 
//This function controls the stylesheet display of either one_column or two.
function style_select() {
		if ($omit_subcontent == true) 
				{ echo '@import url('.SITE_TOP_PATH.'_styles/one_column.css);'; 
				} 
		else { echo '';
				}
		}
//This function controls whether Subcontent bar is shown based one_column option
function subcontent_display() {
		if ($omit_subcontent == true) { echo ''; } 
		else {INCLUDE INCLUDE_PATH.'subcontent.inc.php'; };
		}

// Template Include Functions	

function place_site_name() {
		echo TAGLINE." ".SITE_NAME;
		}
		
function place_top_meta() {
		INCLUDE INCLUDE_PATH.'page_top_meta.inc.php';
		}
		
function place_top_content($site_section) {
		INCLUDE INCLUDE_PATH.'page_top_content.inc.php';
		}
function place_site_path() {
		echo SITE_TOP_PATH;
		}
function place_top() {
		place_top_meta();
		place_top_content($site_section);		
		}
		
function place_header() {
		INCLUDE INCLUDE_PATH.'header.inc.php';
		}
		
function place_menu($site_section) {
		INCLUDE INCLUDE_PATH.'main_menu.inc.php';
		}

function place_footer() {
		INCLUDE INCLUDE_PATH.'footer.inc.php';
		}
		
function place_copyright() {
		echo "&copy;".date(Y).' '.ORG_NAME.'. All Rights Reserved';
		}
		
function place_srlink() {
		INCLUDE INCLUDE_PATH.'sr_link.inc.php';
		}
		
function place_bottom() {
		INCLUDE INCLUDE_PATH.'bottom.inc.php';
		}
// Main Navigation List Generator

function menu_display($links, $site_section) {
    
		 foreach($links as $key=>$value) {
        $class = '';
        $id = '';
    	if ($site_section == $value) {
           $class = ' class="active"';
           $id = ' id="current"'; }
  	echo '<li' . $class . '><a' . $id . ' href="'.SITE_TOP_PATH.$key.'">'.ucfirst($value).'</a></li>'."\n";
     }
    }
?>

page_top_content.inc.php

		<body>
				<div id="page_wrapper">

<?php  
# Place Header
		place_header();
# Place Main Menu
		place_menu($site_section);
?>

<div id="content_wrapper">
<div id="content">


main_menu_inc.php
<div id="menu">
<ul id="navigation">
<?php 
	
//This array defines the links and the site_section names for the links list created by the foreach

		$links = array(''=>'home','blog/'=>'blog','about/'=>'about','contact/'=>'contact');
	
// Display the menu
		
		menu_display($links, $site_section);
?>

</ul>
</div>

I hope this all makes sense. This references thing also makes me wonder if the $omit_subcontent == true will trigger correctly as it is in the functions lib now as well.

Thanks for all the help now and in the future.

All the best,

Jay

#7 smashingred

smashingred
  • Members
  • PipPip
  • Member
  • 15 posts

Posted 18 September 2006 - 03:50 PM

Okay, Ken and other readers. I sortof figured out the use of globals to expand the scope of variables into library functions and now everything seems to be working now. After reading more on php.net in the user examples something seems to have clicked and I have added the globals where needed. See changed functions.php below:

<?php 


//This function controls the stylesheet display of either one_column or two.
function style_select() {
		global $omit_subcontent;
		if ($omit_subcontent == true) 
				{ echo '@import url('.SITE_TOP_PATH.'_styles/one_column.css);'; 
				} 
		else { echo '';
				}
		}
//This function controls whether Subcontent bar is shown based one_column option

function subcontent_display() {
		global $omit_subcontent;
		if ($omit_subcontent == true) { echo ''; } 
		else {INCLUDE INCLUDE_PATH.'subcontent.inc.php'; };
		}

// Template Include Functions	

function place_site_name() {
		echo TAGLINE." ".SITE_NAME;
		}
		
function place_top_meta() {
		global $page_title, $page_keywords, $page_description;
		INCLUDE INCLUDE_PATH.'page_top_meta.inc.php';
		}
		
function place_top_content() {
		INCLUDE INCLUDE_PATH.'page_top_content.inc.php';
		}
function place_site_path() {
		echo SITE_TOP_PATH;
		}
function place_top() {
		place_top_meta();
		place_top_content();		
		}
		
function place_header() {
		INCLUDE INCLUDE_PATH.'header.inc.php';
		}
		
function place_menu() {
		global $site_section;
		INCLUDE INCLUDE_PATH.'main_menu.inc.php';
		}

function place_footer() {
		INCLUDE INCLUDE_PATH.'footer.inc.php';
		}
		
function place_copyright() {
		echo "&copy;".date(Y).' '.ORG_NAME.'. All Rights Reserved';
		}
		
function place_srlink() {
		INCLUDE INCLUDE_PATH.'sr_link.inc.php';
		}
		
function place_bottom() {
		INCLUDE INCLUDE_PATH.'bottom.inc.php';
		}
// Main Navigation List Generator

function menu_display($links) {
		global $site_section;
		 foreach($links as $key=>$value) {
        $class = '';
        $id = '';
    	if ($site_section == $value) {
           $class = ' class="active"';
           $id = ' id="current"'; }
  	echo '<li' . $class . '><a' . $id . ' href="'.SITE_TOP_PATH.$key.'">'.ucfirst($value).'</a></li>'."\n";
     }
    }
?>

Now I have learned that I have to call the global within the function before the operation. Phew. I am glad nobody had come to the rescue yet because I wouldn't have been able figure this out on my own.

Now the only issue is that I want ot make sure that I am not allowing security vulnerabilities with the use of the "global" keyword.

All the best,

Jay




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users