PHP

This overview is a bare outline of the real deal.

Almost finished — flesh out objects as arguments.

PHP can pass arguments to functions

by value

function inc($n) { // $n gets $a's value
	$n++; // only $n is altered
	return $n;
}
$a=1;
echo ( inc($a) ); // produces 2

Calling inc($a) repeatedly doesn't alter $a.

by reference &

function inc(&$n) { // $n refers to $a
	$n++; // $a is altered — no need to "return $n"
}
$a=1;
inc($a);
echo ( $a ); // produces 2

Repeated calls to inc($a) bump $a to 3, 4, 5, etc.

(Note: echo inc($a) produces null, since inc() returns no value.)

with default values

Arguments with default values:

The 1st call below has no $host value, the 3rd an empty one, "".

function create_email( $name, $account, $host='@uw.edu' ) {
	return '"' . addslashes($name) . '"' . '<' . $account . $host . '>';
}
create_email( "Jim O'Rourke", "jorourke"   ); // "Jim O\'Rourke" <jorourke@uw.edu>
create_email( "Buster Keaton", "bkeaton", "@hotmail.com" ); // "Buster Keaton" <bkeaton@hotmail.com>
create_email( "Annie Dillard", "adillard", "" ); // "Annie Dillard" <adillard>

PHP isn't very flexible about this. You'd expect the following to work, but it produces an error:

function employee( $name, $room, $bld='PDL', $role='faculty', $hours='8:00 - 5:00' ) {
	return $name . ', ' . $role . ', ' . $bld . ' ' . $room . ' ' . $hours;
}
// the next line lacks values for $bld and $role, but PHP doesn't insert the defaults ?!?
echo employee( 'John Webster','A-407',,,'By Appointment' ); 

Associative arrays can work around this odd limitation. You can test keys, providing values when they're missing.

3 default values are supplied below.

function employees($arr) {
	$s='';
	foreach($arr as $arr2) {
		$s .= "\n{$arr2['name']}, ";
		$s .= (isset($arr2['role'])) ? $arr2['role'] . ', ' : 'faculty, ';
		$s .= (isset($arr2['bld'])) ? $arr2['bld'] . ' ' : 'PDL ' ;
		$s .= $arr2['room'] . ', ';
		$s .= (isset($arr2['hours'])) ? $arr2['hours'] . '.' : '8:00-5:00.' ;
	}
	return "$s";
}
$a[] = array( 'name'=>'John Webster', 'room'=>'A-407', 'hours'=>'By Appt' );
$a[] = array( 'name'=>'Kathy Mork', 'role'=>'staff', 'room'=>'A-107'  );
$a[] = array( 'name'=>'Jim O\'Rourke', 'role'=>'student', 'bld'=>'ART', 'room'=>'347', 'hours'=>'2:00-4:00 MW'  );
echo employees( $a );

Because the keys are tested, they can appear in any order in the array passed to employees().

variable numbers of arguments

Sometimes, you can't know how many arguments a function might receive.

PHP provides for this with 3 functions:

This function assumes all arguments are numbers.

function average() {
	if (func_num_args() > 0) {
		$sum=0;
		for ( $i=0; $i< func_num_args(); ++$i ) $sum += func_get_arg($i);
		return ($sum / func_num_args());
	}
}
average(1,2,3,4); // 2.5
average(3,6,9,12,15,18,21) // 12

The FOR loop above illustrates func_get_arg().

FOREACH with func_get_args() is more compact and a little faster:
foreach ( func_get_args() as $v ) $sum += $v;

Cleaner yet (though a smidgen slower):

function addem($r, $v) {
    $r += $v; // add to $r the incoming value $v
    return $r; // send $r back
}
function average($arr) {
    if (func_num_args() > 0) {
		$sum = array_reduce( func_get_args(), 'addem' );
		return ( $sum / func_num_args() );
    }
}
Or, more compactly:
function addem($r, $v) {
	return ( $r += $v ); 
}
function average($arr) {
	if (func_num_args() > 0) {
		return ( array_reduce( func_get_args(), 'addem' ) / func_num_args() );
	}
}

About array_reduce().

Array_reduce() returns the result of an operation performed recursively on each value in an array. (In the example above, the operation is a simple addition which results in the sum of the array's values.)

Array_reduce takes an array name and a function name, then passes 2 things to the function:

The function receives these as 2 arguments (above, $r and $v).

The function returns a value, and array_reduce() stores it in the result variable.

Then it calls the function again, sending back the result variable and the next value in the array.

This continues, the result variable being updated each time, until the array is exhausted.

Then array_reduce() returns the value of the result variable to the calling code.

Hence array_reduce() / func_num_args() = the average.

So, array_reduce can replace both the $sum variable and the FOR loop in the earlier code.

variable types of arguments

If a function needs to take arguments of different data types, you can test the type.

function x() {
	foreach (func_get_args() as $v) {
		if (is_string($v)) do_string_thing();
		if (is_int(($v)) do_number_thing();
		if (is_bool(($v)) do_boolean_thing();
	}
}

Or, you could fall back on the associative array strategy and test key names.

function makebib($arr) {
	$s='';
	foreach($arr as $arr2) { // loop through outer array
		$s .= "\n<p>";
		foreach($arr2 as $k=>$v) { // process keys:values of inner array
			switch ($k) {
				case 'author':
					$s .= "$v. ";
					break;
				case 'booktitle':
				case 'pubtitle':
					$s .= "<cite>$v.</cite> ";
					break;
				case 'articletitle':
				case 'chaptertitle':
					$s .= "\"$v\". ";
					break;
				case 'vol': // if calculated from year
 					$s .= "$v"; // the calculation could happen here
					break;
				case 'issue':
					$s .= ".$v";
					break;
				case 'pubyear':
					$s .= " ($v): ";
					break;	
				case 'first_published':
					$s .= "First published in $v.";
					break;
				case 'pages':
					$s .= "$v.";
					break;
			}
		}
		$s .= '</p>';
	}
	return $s;
}
$bib[] = array('author'=>'Joseph Conrad','booktitle'=>'Heart of Darkness', 'first_published'=>'1902');
$bib[] = array('author'=>'Gayatri Chakravorty Spivak','articletitle'=>'Why Study the Past', 
	'pubtitle'=>'Modern Language Quarterly', 'vol'=>'73', 'issue'=>'1', 
	'pubyear'=>'2013', 'pages'=>'31-43');

echo makebib($bib);

Producing:

Joseph Conrad. Heart of Darkness. First published in 1902.

Gayatri Chakravorty Spivak. "Why Study the Past". Modern Language Quarterly. 73.1 (2013): 31-43.

Hardcoding the $bib array for this example is annoyingly prolix with all the repeated key names. In a real bit of code, you'd likely fill the array programmatically while processing the results from a query or an XML, JSON, or CSV file.

In any event, passing an associative array easily allows for multiple default values and variable numbers of arguments.

As does passing an object.

example of processing an object argument . . .

explore under "Classes/Object Functions" PHP manual: