Function arguments
Информация может быть передана функциям через список аргументов, который представляет собой список выражений, разделенных запятыми. Аргументы оцениваются слева направо перед фактическим вызовом функции ( жадная оценка).
Пример # 1 Передача массивов функциям
function takes_array($input) < echo "$input[0] + $input[1] = ", $input[0]+$input[1]; > ?>
Начиная с PHP 8.0.0,список аргументов функции может включать запятую,которая будет проигнорирована.Это особенно полезно в тех случаях,когда список аргументов длинный или содержит длинные имена переменных,что делает удобным вертикальное расположение аргументов.
Пример # 2 Список аргументов функции с запятой в конце
function takes_many_args( $first_arg, $second_arg, $a_very_long_argument_name, $arg_with_default = 5, $again = 'a default string', // This trailing comma was not permitted before 8.0.0. ) < // . > ?>
Передача аргументов по ссылке
По умолчанию аргументы функции передаются по значению (чтобы при изменении значения аргумента внутри функции оно не менялось вне функции).Чтобы функция могла изменять свои аргументы,они должны передаваться по ссылке.
Чтобы аргумент функции всегда передавался по ссылке, добавьте амперсанд (&) к имени аргумента в определении функции:
Пример #3 Передача параметров функции по ссылке
function add_some_extra(&$string) < $string .= 'and something extra.'; > $str = 'This is a string, '; add_some_extra($str); echo $str; // outputs 'This is a string, and something extra.' ?>
Ошибкой является передача в качестве аргумента значения,которое должно быть передано по ссылке.
Значения аргументов по умолчанию
Функция может определять значения по умолчанию для аргументов, используя синтаксис, аналогичный назначению переменной. Значение по умолчанию используется только тогда, когда параметр не указан; в частности, обратите внимание, что передача null не присваивает значение по умолчанию.
Пример #4 Использование параметров по умолчанию в функциях
function makecoffee($type = "cappuccino") < return "Making a cup of $type.\n"; > echo makecoffee(); echo makecoffee(null); echo makecoffee("espresso"); ?>
Выводится приведенный выше пример:
Making a cup of cappuccino. Making a cup of . Making a cup of espresso.
Значения параметров по умолчанию могут быть скалярными значениями, массивами, специальным типом null и, начиная с PHP 8.1.0, объектами, использующими новый синтаксис ClassName().
Пример #5 Использование нескалярных типов в качестве значений по умолчанию
function makecoffee($types = array("cappuccino"), $coffeeMaker = NULL) < $device = is_null($coffeeMaker) ? "hands" : $coffeeMaker; return "Making a cup of ".join(", ", $types)." with $device.\n"; > echo makecoffee(); echo makecoffee(array("cappuccino", "lavazza"), "teapot");?>
Пример #6 Использование объектов в качестве значений по умолчанию (начиная с PHP 8.1.0)
class DefaultCoffeeMaker < public function brew() < return 'Making coffee.'; > > class FancyCoffeeMaker < public function brew() < return 'Crafting a beautiful coffee just for you.'; > > function makecoffee($coffeeMaker = new DefaultCoffeeMaker) < return $coffeeMaker->brew(); > echo makecoffee(); echo makecoffee(new FancyCoffeeMaker); ?>
Значение по умолчанию должно быть константным выражением,а не (например)переменной,членом класса или вызовом функции.
Обратите внимание,что любые необязательные аргументы должны быть указаны после всех обязательных аргументов,иначе их нельзя будет опустить в вызове.Рассмотрим следующий пример:
Пример # 7 Неправильное использование аргументов функции по умолчанию
function makeyogurt($container = "bowl", $flavour) < return "Making a $container of $flavour yogurt.\n"; > echo makeyogurt("raspberry"); // "raspberry" is $container, not $flavour ?>
Выводится приведенный выше пример:
Fatal error: Uncaught ArgumentCountError: Too few arguments to function makeyogurt(), 1 passed in example.php on line 42
Пример # 8 Правильное использование аргументов функции по умолчанию
function makeyogurt($flavour, $container = "bowl") < return "Making a $container of $flavour yogurt.\n"; > echo makeyogurt("raspberry"); // "raspberry" is $flavour ?>
Выводится приведенный выше пример:
Making a bowl of raspberry yogurt.
Начиная с PHP 8.0.0, именованные аргументы можно использовать для пропуска нескольких необязательных параметров.
Пример #9 Правильное использование аргументов функции по умолчанию
function makeyogurt($container = "bowl", $flavour = "raspberry", $style = "Greek") < return "Making a $container of $flavour $style yogurt.\n"; > echo makeyogurt(style: "natural"); ?>
Выводится приведенный выше пример:
Making a bowl of raspberry natural yogurt.
Начиная с PHP 8.0.0, объявление обязательных аргументов после необязательных аргументов устарело . Как правило, это можно решить, отбросив значение по умолчанию, поскольку оно никогда не будет использоваться. Единственным исключением из этого правила являются аргументы формы Type $param = null , где значение по умолчанию null делает тип неявно допускающим значение null. Это использование остается разрешенным, хотя вместо этого рекомендуется использовать явный тип, допускающий значение NULL .
Пример #10 Объявление необязательных аргументов после обязательных аргументов
function foo($a = [], $b) <> // Default not used; deprecated as of PHP 8.0.0 function foo($a, $b) <> // Functionally equivalent, no deprecation notice function bar(A $a = null, $b) <> // Still allowed; $a is required but nullable function bar(?A $a, $b) <> // Recommended ?>
Примечание . Начиная с PHP 7.1.0, пропуск параметра, который не указывает значение по умолчанию, приводит к ошибке ArgumentCountError ; в предыдущих версиях выдавалось предупреждение.
Примечание . Аргументы, переданные по ссылке, могут иметь значение по умолчанию.
Списки аргументов переменной длины
PHP поддерживает списки аргументов переменной длины в пользовательских функциях с помощью токена . .
Примечание. Аргументы переменной длины также можно получить с помощью функций func_num_args () , func_get_arg () и func_get_args () . Этот метод не рекомендуется, поскольку он использовался до введения токена . .
Списки аргументов могут включать токен . для обозначения того, что функция принимает переменное количество аргументов. Аргументы будут переданы в данную переменную в виде массива; Например:
Пример #11 Использование . для доступа к переменным аргументам
function sum(. $numbers) < $acc = 0; foreach ($numbers as $n) < $acc += $n; > return $acc; > echo sum(1, 2, 3, 4); ?>
Выводится приведенный выше пример:
. также можно использовать при вызове функций для распаковки массива, переменной или литерала Traversable в список аргументов:
Пример #12 Использование . для предоставления аргументов
function add($a, $b) < return $a + $b; > echo add(. [1, 2])."\n"; $a = [1, 2]; echo add(. $a); ?>
Выводится приведенный выше пример:
Вы можете указать обычные позиционные аргументы перед токеном . .В этом случае, только завершающие аргументы , которые не соответствуют позиционному аргументу будут добавлены в массив , порожденный . .
Также можно добавить объявление типа перед токеном . .Если он присутствует, то все аргументы, захваченные . , должны соответствовать этому типу параметра.
Пример #13 Тип аргументов объявленной переменной
function total_intervals($unit, DateInterval . $intervals) < $time = 0; foreach ($intervals as $interval) < $time += $interval->$unit; > return $time; > $a = new DateInterval('P1D'); $b = new DateInterval('P2D'); echo total_intervals('d', $a, $b).' days'; // This will fail, since null isn't a DateInterval object. echo total_intervals('d', null); ?>
Выводится приведенный выше пример:
3 days Catchable fatal error: Argument 2 passed to total_intervals() must be an instance of DateInterval, null given, called in - on line 14 and defined in - on line 2
Наконец, переменные аргументы также могут быть переданы по ссылке , поставив перед . префиксом амперсанд ( & ).
Старые версии PHP
Чтобы отметить, что функция является переменной, не требуется специального синтаксиса; однако для доступа к аргументам функции необходимо использовать функции func_num_args () , func_get_arg () и func_get_args () .
В старых версиях PHP первый пример был бы реализован следующим образом:
Пример #14 Доступ к переменным аргументам в старых версиях PHP
function sum( ) < $acc = 0; foreach (func_get_args() as $n) < $acc += $n; > return $acc; > echo sum(1, 2, 3, 4); ?>
Выводится приведенный выше пример:
Function string argument php
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;
>
Function string argument php
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».
*/
?>