PHP Named Arguments
Summary: in this tutorial, you will learn about PHP named arguments and how to use them effectively in your code.
Introduction to the PHP named arguments
Since PHP 8.0, you can use named arguments for functions. The named arguments allow you to pass arguments to a function based on the parameter names rather than the parameter positions.
The following example defines a function that finds the position of the first occurrence of a substring in a string:
function find($needle, $haystack) < return strpos($haystack, $needle); >
Code language: HTML, XML (xml)
To call the find() function, you pass the arguments based on the parameter positions like this:
find('awesome', 'PHP is awesome!');
Code language: JavaScript (javascript)
In this case, $needle is ‘awesome’ and $haystack is ‘PHP is awesome!’ .
However, the function call is not apparent. For example, you don’t know which argument is the needle and which argument is the haystack.
Sometimes, you may accidentally make a mistake by passing the arguments in the wrong order. For example:
find ( 'PHP is awesome!', 'awesome' );
Code language: JavaScript (javascript)
This is buggy and very difficult to troubleshoot.
To avoid this, you may add comments to the arguments like this:
find ( 'awesome', // needle 'PHP is awesome!' // haystack );
Code language: JavaScript (javascript)
The comment makes the code more clear. However, it’s not robust.
To improve this, PHP 8.0 introduced the named arguments that allow you to specify the parameter names when passing arguments:
find ( $needle : 'awesome', $haystack : 'PHP is awesome!' );
Code language: PHP (php)
Since you are using the parameter names, the positions are not necessary. For example, you can swap the parameters like this:
find( $haystack :'PHP is awesome!', $needle : 'awesome' );
Code language: PHP (php)
Skipping default arguments
The following defines a function that creates an anchor element ( ) from text, href, title, and target:
function create_anchor( $text, $href = '#', $title = '', $target = '_self' ) < $href = $href ? sprintf('href="%s"', $href) : ''; $title = $title ? sprintf('title="%s"', $title) : ''; $target = $target ? sprintf('target="%s"', $target) : ''; return "$text"; >
Code language: HTML, XML (xml)
To create a link with the target is _blank , you must specify all the default arguments until the one you want to change. For example:
$link = create_anchor( 'PHP Tutorial', 'https://www.phptutorial.net/', '', '_blank' ); echo $link;
Code language: PHP (php)
a href="https://www.phptutorial.net/" target="_blank">
PHP Tutorial a> Code language: HTML, XML (xml)
In this example, you need to pass the space (”) to the third argument. If you use the named arguments, you don’t have to specify all the defaults. For example:
$link = create_anchor( text : 'PHP Tutorial', href : 'https://www.phptutorial.net/', target: '_blank' );
Code language: PHP (php)
Mixing named arguments with positional arguments
PHP allows you to call a function by using both positional arguments and named arguments. And you need to place the named arguments after positional arguments. For example:
$link = create_anchor( 'PHP Tutorial', 'https://www.phptutorial.net/', target: '_blank' );
Code language: PHP (php)
- The text is ‘PHP Tutorial’ .
- The href is ‘https://www.phptutorial.net/’ .
- And the target is ‘_blank’ .
If you place the named arguments before the positional arguments, you’ll get an error. For example:
create_anchor( target : '_blank', 'PHP Tutorial', 'https://www.phptutorial.net/' );
Code language: JavaScript (javascript)
Cannot use positional argument after named argument
Code language: PHP (php)
Summary
- Use PHP named arguments to pass arguments to a function based on the parameter names.
- Put the named arguments after the positional arguments in function calls.
Php function parameters string
To experiment on performance of pass-by-reference and pass-by-value, I used this script. Conclusions are below.
#!/usr/bin/php
function sum ( $array , $max ) < //For Reference, use: "&$array"
$sum = 0 ;
for ( $i = 0 ; $i < 2 ; $i ++)#$array[$i]++; //Uncomment this line to modify the array within the function.
$sum += $array [ $i ];
>
return ( $sum );
>
$max = 1E7 //10 M data points.
$data = range ( 0 , $max , 1 );
$start = microtime ( true );
for ( $x = 0 ; $x < 100 ; $x ++)$sum = sum ( $data , $max );
>
$end = microtime ( true );
echo «Time: » .( $end — $start ). » s\n» ;
/* Run times:
# PASS BY MODIFIED? Time
— ——- ——— —-
1 value no 56 us
2 reference no 58 us
3 valuue yes 129 s
4 reference yes 66 us
1. PHP is already smart about zero-copy / copy-on-write. A function call does NOT copy the data unless it needs to; the data is
only copied on write. That’s why #1 and #2 take similar times, whereas #3 takes 2 million times longer than #4.
[You never need to use &$array to ask the compiler to do a zero-copy optimisation; it can work that out for itself.]
2. You do use &$array to tell the compiler «it is OK for the function to over-write my argument in place, I don’t need the original
any more.» This can make a huge difference to performance when we have large amounts of memory to copy.
(This is the only way it is done in C, arrays are always passed as pointers)
3. The other use of & is as a way to specify where data should be *returned*. (e.g. as used by exec() ).
(This is a C-like way of passing pointers for outputs, whereas PHP functions normally return complex types, or multiple answers
in an array)
5. Sometimes, pass by reference could be at the choice of the caller, NOT the function definitition. PHP doesn’t allow it, but it
would be meaningful for the caller to decide to pass data in as a reference. i.e. «I’m done with the variable, it’s OK to stomp
on it in memory».
*/
?>
Php function parameters string
While waiting for native support for typed arrays, here are a couple of alternative ways to ensure strong typing of arrays by abusing variadic functions. The performance of these methods is a mystery to the writer and so the responsibility of benchmarking them falls unto the reader.
PHP 5.6 added the splat operator (. ) which is used to unpack arrays to be used as function arguments. PHP 7.0 added scalar type hints. Latter versions of PHP have further improved the type system. With these additions and improvements, it is possible to have a decent support for typed arrays.
function typeArrayNullInt (? int . $arg ): void >
function doSomething (array $ints ): void (function (? int . $arg ) <>)(. $ints );
// Alternatively,
( fn (? int . $arg ) => $arg )(. $ints );
// Or to avoid cluttering memory with too many closures
typeArrayNullInt (. $ints );
function doSomethingElse (? int . $ints ): void /* . */
>
$ints = [ 1 , 2 , 3 , 4 , null ];
doSomething ( $ints );
doSomethingElse (. $ints );
?>
Both methods work with all type declarations. The key idea here is to have the functions throw a runtime error if they encounter a typing violation. The typing method used in doSomethingElse is cleaner of the two but it disallows having any other parameters after the variadic parameter. It also requires the call site to be aware of this typing implementation and unpack the array. The method used in doSomething is messier but it does not require the call site to be aware of the typing method as the unpacking is performed within the function. It is also less ambiguous as the doSomethingElse would also accept n individual parameters where as doSomething only accepts an array. doSomething’s method is also easier to strip away if native typed array support is ever added to PHP. Both of these methods only work for input parameters. An array return value type check would need to take place at the call site.
If strict_types is not enabled, it may be desirable to return the coerced scalar values from the type check function (e.g. floats and strings become integers) to ensure proper typing.
same data type and same value but first function declare as a argument type declaration and return int(7)
and second fucntion declare as a return type declaration but return int(8).
function argument_type_declaration(int $a, int $b) return $a+$b;
>
function return_type_declaration($a,$b) :int return $a+$b;
>