This overview is a bare outline of the real deal.
Almost finished — flesh out objects as arguments.
PHP can pass arguments to functions
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.
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.)
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().
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() ); } }
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: