Help with foreach loop in function - groan

Hi everyone,

you know I love functions - right? And I’ll probably master them in the next decade or so, but can someone please help me out with my present problem?

OK, I have a series of foreach loops which I’d like to replace with a function.

The original loop:

if(isset($myarray)) {

foreach ($myarray as $v) {

$_SESSION['xyz'] = "the fruit is '$v'";
$_SESSION['fruits'] = $v;

}
}

My attempt at creating the function:

function fruits($arg1,$arg2,$arg3,$arg4) {
	
foreach ($arg1 as $v) {
$arg2[] = $arg3;
$arg4[] = $v;

}	
}

Calling the function:

if(isset($myarray)) {

fruits($myarray,$_SESSION['xyz'],"the fruit is '$v'",$_SESSION['fruits']);

}

Should I be returning $arg2 and $arg4?

Thanks for any assistance. :smile:

As I read that (and I am no expert) you’re passing in the values of two session variables to the function, so my head can’t see how you can then use those values as arrays within the function. If your function will always be updating session variables, wouldn’t it be better just to pass in the variable names?

fruits($myarray, 'xyz', "the fruit is '$v''", 'fruits');
...
function fruits($arg1, $arg2, $arg3, $arg4) {

foreach ($arg1 as $v) {
   $_SESSION[$arg2] = $arg3; // though I'm not sure if the variable substitution will work here
   $_SESSION[$arg4] = $v;
   }
}

Is it your intention to replace the session variable contents each time you run through the loop (as your original code appears to do), or do you want to build up an array for each? You might have to pass the third argument in surrounded by single quotes instead of double quotes, in case the $v variable gets substituted before the call, or perhaps escape the varname - I’m not really familiar with auto substitution, I tend to explicitly replace as required.

So perhaps you could explain exactly what you want the function to do, and what your code is doing that doesn’t match requirement? I don’t think you can return two values from a function, you’d have to use global variables for that.

Hi droopsnoot,

thank you for replying.

I’ve scrapped my sessions and substituted those with regular arrays - I actually do want to loop all of the values into the two arrays.

I have a number of arrays and I need to run a foreach loop on all of them, so I thought I could use a function and save some time.

In your example you used $_SESSION[$arg4] = $v; Do you think I can use a standard array instead? What I mean is that I need to use those arrays that I passed into the function as arguments. So I’d use the $myarray argument as in $myarray = $v;

Thanks.

I don’t think you can return two values from a function, you’d have to use global variables for that.

You certainly can, indirectly. A function dealing with 2d coordinates might do this.

return array ('height' => $height, 'width' => $width);

This is also why PHP added function array deferencing in 5.4. Suppose you called a function with that return but only need the width. You can call

$width = coordFunction($args)['width'];

Another way to handle complex returns is to encapsulate them in an object. You’ve probably already done this without knowing - the implicit return of a __construct function is

return $this;

As to the original post, you really need to use more descriptive variable names than $arg1, $arg2 et al. I can’t grok what you’re trying to do here at all. One option is to receive $arg 2 and $arg 4 by reference to retain the changes you make to those variables in the function. It looks like this

function fruits( $arg1, &$arg2, $arg3, &$arg4)

That said, receiving arguments by reference makes for difficult to test code, and the technique is really only meant for arguments that have (or at least have the potential to have) a large memory footprint. Normally function should leave their arguments alone.

EDIT: For more information see Passing By Reference. Also, if you have a C or C++ background do not confuse PHP references for pointers. They aren’t exactly the same thing, though they are used in similar ways.

Hi @RedBishop

Try this example by Value and by Reference:

<?php 
 //====================================
 function fnDebug($val, $title='NOT SET')
 {
 	echo '<pre>';
	 	echo '<h4>' .$title .'</h4>';
 	  print_r($val);
 	echo '</pre>';
 }##	

 //================================
 function byValue($fruitZ, $result)
 {
 	foreach($fruitZ as $fruit) 
 	{
 		$result[$fruit] = $fruit;
 	}

  return $result;
 }##


 //================================
 function byRef($fruitZ, & $result, & $resultTwo=array())
 {
 	foreach($fruitZ as $fruit) 
 	{
 		$result[$fruit] = $fruit;
 	}

 	$resultTwo = $result; 
 }##


 $fruits = array 
 (
 	'apples',
 	'oranges',
 	'pears',
 	'bananas',
 );


?><!doctype html>
<html>
<head>
	<style>
		body {background-color:#ddd;}
		pre,
		div  {clear:both; margin:1em auto; background-color:snow; border:solid 1px #999; padding:1em;}
		pre	 {float:left;}
	</style>
	<title>Untitled Document</title>
</head>

<body>

	<?php 
		echo '<div style="background-color:#cff;">';
			echo 'Pass by Value: ================ <br />';

			$result = array();
			
			fnDebug( $fruits, '$fruits: before' );
			fnDebug( $result, '$result: before' );

			$result = byValue( $fruits, $result );

			fnDebug( $fruits, '$fruits: after' );
			fnDebug( $result, '$result: after' );

			echo '<br style="clear:both;" />' ;
		echo '</div>';	

		echo '<div style="background-color:#cfc;">';
			echo 'Pass by Reference: ============ <br />';
			$byRef    = array();
			$byRefTwo = array();
			
			fnDebug( $fruits,   '$fruits:   before' );
			fnDebug( $byRef,    '$byRef:    before' );
			fnDebug( $byRefTwo, '$byRefTwo: before' );

			byRef( $fruits, $byRef, $byRefTwo );

			fnDebug( $fruits,   '$fruits:   after' );
			fnDebug( $byRef,    '$byRef:    after' );
			fnDebug( $byRefTwo, '$byRefTwo: after' );

			echo '<br style="clear:both;" />';
		echo '</div>';	
		?>

		<div>
			Source:
			<?php highlight_file(__FILE__);?>
		</div>

</body>
</html>

Hi Michael_Morris & John_Betong,

thank you so much for your help!!

Yes, after using this method the function is now working, although I do have to use more descriptive variable names as you pointed out. I’m already confused enough as it is. LOL.

One thing I’m wondering about, would OOP help in this regard? Would I still have to use functions with referenced arguments, or no functions at all?

@John_Betong

Thank you for that extensive example! Really appreciate it.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.