Как пропустить необязательные аргументы в вызове функции?
OK Я полностью забыл, как пропускать аргументы в PHP.
Допустим, у меня есть:
function getData($name, $limit = '50', $page = '1') {
...
}
Как я могу назвать эту функцию так, чтобы средний параметр принимал значение по умолчанию (например, "50" )?
getData('some name', '', '23');
Правильно ли это было бы? Кажется, я не могу заставить это работать.
Ответы
Ответ 1
Ваше сообщение верное.
К сожалению, если вам нужно использовать необязательный параметр в самом конце списка параметров, вам нужно указать все до последнего параметра. Как правило, если вы хотите смешивать и сопоставлять, вы даете им значения по умолчанию ''
или null
и не используете их внутри функции, если они являются значением по умолчанию.
Ответ 2
Нет способа "пропустить" аргумент, кроме как указать значение по умолчанию, например false
или null
.
Поскольку у PHP не хватает синтаксического сахара, когда дело доходит до этого, вы часто увидите что-то вроде этого:
checkbox_field(array(
'name' => 'some name',
....
));
Что, как красноречиво сказано в комментариях, использует массивы для эмуляции именованных аргументов.
Это дает максимальную гибкость, но в некоторых случаях может не понадобиться. По крайней мере, вы можете перемещать то, что, по вашему мнению, не ожидается в большинстве случаев до конца списка аргументов.
Ответ 3
Нет, невозможно пропустить аргументы таким образом. Вы можете пропустить передающие аргументы только, если они находятся в конце списка параметров.
Было официальное предложение для этого: https://wiki.php.net/rfc/skipparams, который получил отказ. Страница предложения связана с другими вопросами SO по этой теме.
Ответ 4
Ничего не изменилось в отношении возможности пропустить необязательные аргументы, однако для правильного синтаксиса и для возможности указать NULL для аргументов, которые я хочу пропустить, вот как я это сделаю:
define('DEFAULT_DATA_LIMIT', '50');
define('DEFAULT_DATA_PAGE', '1');
/**
* getData
* get a page of data
*
* Parameters:
* name - (required) the name of data to obtain
* limit - (optional) send NULL to get the default limit: 50
* page - (optional) send NULL to get the default page: 1
* Returns:
* a page of data as an array
*/
function getData($name, $limit = NULL, $page = NULL) {
$limit = ($limit==NULL) ? DEFAULT_DATA_LIMIT : $limit;
$page = ($page==NULL) ? DEFAULT_DATA_PAGE : $page;
...
}
Это можно вызвать следующим образом: getData('some name',NULL,'23');
, и каждый, вызывающий функцию в будущем, не должен помнить значения по умолчанию каждый раз или объявленную для них константу.
Ответ 5
Простой ответ Нет. Но почему пропустить, когда переустановка аргументов достигает этого?
У вас есть " Неправильное использование аргументов функции по умолчанию" и не будет работать так, как вы ожидаете.
Замечание из документации PHP:
При использовании аргументов по умолчанию любые значения по умолчанию должны быть в правой части любых аргументов, отличных от значения по умолчанию; в противном случае все будет работать не так, как ожидалось.
Рассмотрим следующее:
function getData($name, $limit = '50', $page = '1') {
return "Select * FROM books WHERE name = $name AND page = $page limit $limit";
}
echo getData('some name', '', '23'); // won't work as expected
Выход будет:
"Select * FROM books WHERE name = some name AND page = 23 limit"
Правильное использование аргументов функции по умолчанию должно быть таким:
function getData($name, $page = '1', $limit = '50') {
return "Select * FROM books WHERE name = $name AND page = $page limit $limit";
}
echo getData('some name', '23'); // works as expected
Выход будет:
"Select * FROM books WHERE name = some name AND page = 23 limit 50"
Устанавливая значение по умолчанию справа от значений, отличных от значений по умолчанию, убедитесь, что он всегда будет перенастраивать значение по умолчанию для этой переменной, если оно не определено/задано
Вот ссылка для ссылки и откуда взялись эти примеры.
Изменить: настройка на null
, как другие могут предлагать, может работать, и это еще одна альтернатива, но может не соответствовать тому, что вы хотите. Он всегда устанавливает значение по умолчанию равным null, если оно не определено.
Ответ 6
Вы не можете пропустить аргументы, но можете использовать параметры массива, и вам нужно определить только один параметр, который представляет собой массив параметров.
function myfunction($array_param)
{
echo $array_param['name'];
echo $array_param['age'];
.............
}
И вы можете добавить столько параметров, сколько вам нужно, вам не нужно их определять. Когда вы вызываете функцию, вы вводите свои параметры следующим образом:
myfunction(array("name" => "Bob","age" => "18", .........));
Ответ 7
Как уже упоминалось выше, вы не сможете пропустить параметры. Я написал этот ответ, чтобы предоставить некоторое добавление, которое было слишком большим, чтобы разместить комментарий.
@Frank Nocke предлагает вызывать функцию с ее параметрами по умолчанию, поэтому, например, имея
function a($b=0, $c=NULL, $d=''){ //...
вы должны использовать
$var = a(0, NULL, 'ddd');
который будет функционировать так же, как опустить первые два параметра ($b
и $c
).
Непонятно, какие из них по умолчанию (0
напечатано для указания значения по умолчанию, или это важно?).
Существует также опасность того, что проблема по умолчанию связана с внешней (или встроенной) функцией, когда значения по умолчанию могут быть изменены автором функции (или метода). Поэтому, если вы не измените свой вызов в программе, вы можете непреднамеренно изменить его поведение.
Некоторое обходное решение может заключаться в определении некоторых глобальных констант, таких как DEFAULT_A_B
, которые будут "значением по умолчанию для параметра B параметра функции A" и "опустить" следующим образом:
$var = a(DEFAULT_A_B, DEFAULT_A_C, 'ddd');
Для классов это проще и элегантнее, если вы определяете константы класса, потому что они являются частью глобальной области, например.
class MyObjectClass {
const DEFAULT_A_B = 0;
function a($b = self::DEFAULT_A_B){
// method body
}
}
$obj = new MyObjectClass();
$var = $obj->a(MyObjectClass::DEFAULT_A_B); //etc.
Обратите внимание, что эта константа по умолчанию определена ровно один раз на протяжении всего кода (нет значения даже в объявлении метода), поэтому в случае непредвиденных изменений вы всегда будете снабжать функцию/метод правильным значением по умолчанию.
Ясность этого решения, конечно, лучше, чем предоставление исходных значений по умолчанию (например, NULL
, 0
и т.д.), которые ничего не говорят читателю.
(Я согласен с тем, что вызов как $var = a(,,'ddd');
будет лучшим вариантом)
Ответ 8
Для любого параметра, пропущенного (вы должны) пойти с параметром по умолчанию, чтобы быть в безопасности.
(Settling for null, где параметр по умолчанию "или", или наоборот, приведет вас к неприятности...)
Ответ 9
Ну как и все остальные сказали, что то, что вы хотите, не будет возможно в PHP без добавления каких-либо кодовых строк в функции.
Но вы можете поместить этот фрагмент кода в начало функции, чтобы получить вашу функциональность:
foreach((new ReflectionFunction(debug_backtrace()[0]["function"]))->getParameters() as $param) {
if(empty(${$param->getName()}) && $param->isOptional())
${$param->getName()} = $param->getDefaultValue();
}
Итак, в основном с debug_backtrace()
Я получаю имя функции, в которой этот код помещен, чтобы затем создать новый ReflectionFunction
объект и цикл, хотя все аргументы функции.
В цикле я просто проверяю, является ли аргумент функции empty()
И аргумент "необязательный" (означает, что он имеет значение по умолчанию). Если да, я просто присваиваю значение по умолчанию аргументу.
Demo
Ответ 10
Установите предел в значение null
function getData($name, $limit = null, $page = '1') {
...
}
и вызов этой функции
getData('some name', null, '23');
если вы хотите установить предел, который вы можете передать в качестве аргумента
getData('some name', 50, '23');
Ответ 11
Как было сказано ранее, ничего не изменилось.
Остерегайтесь, однако, слишком много параметров (особенно дополнительных) - сильный индикатор запаха кода.
Возможно, ваша функция слишком много:
// first build context
$dataFetcher->setPage(1);
// $dataFetcher->setPageSize(50); // not used here
// then do the job
$dataFetcher->getData('some name');
Некоторые параметры могут быть сгруппированы логически:
$pagination = new Pagination(1 /*, 50*/);
getData('some name', $pagination);
// Java coders will probably be familiar with this form:
getData('some name', new Pagination(1));
В последнем случае вы всегда можете ввести специальный объект :
$param = new GetDataParameter();
$param->setPage(1);
// $param->setPageSize(50); // not used here
getData($param);
(это просто прославленная версия менее формальной метода массива параметров)
Иногда сама причина внесения параметра необязательна. В этом примере $page
действительно означает, что это необязательно? Действительно ли сохранение нескольких символов действительно имеет значение?
// dubious
// it is not obvious at first sight that a parameterless call to "getData()"
// returns only one page of data
function getData($page = 1);
// this makes more sense
function log($message, $timestamp = null /* current time by default */);
Ответ 12
Этот фрагмент:
function getData($name, $options) {
$default = array(
'limit' => 50,
'page' => 2,
);
$args = array_merge($default, $options);
print_r($args);
}
getData('foo', array());
getData('foo', array('limit'=>2));
getData('foo', array('limit'=>10, 'page'=>10));
Ответ:
Array
(
[limit] => 50
[page] => 2
)
Array
(
[limit] => 2
[page] => 2
)
Array
(
[limit] => 10
[page] => 10
)
Ответ 13
Это то, что я сделал бы:
<?php
function getData($name, $limit = '', $page = '1') {
$limit = (EMPTY($limit)) ? 50 : $limit;
$output = "name=$name&limit=$limit&page=$page";
return $output;
}
echo getData('table');
/* output name=table&limit=50&page=1 */
echo getData('table',20);
/* name=table&limit=20&page=1 */
echo getData('table','',5);
/* output name=table&limit=50&page=5 */
function getData2($name, $limit = NULL, $page = '1') {
$limit = (ISSET($limit)) ? $limit : 50;
$output = "name=$name&limit=$limit&page=$page";
return $output;
}
echo getData2('table');
// /* output name=table&limit=50&page=1 */
echo getData2('table',20);
/* output name=table&limit=20&page=1 */
echo getData2('table',NULL,3);
/* output name=table&limit=50&page=3 */
?>
Надеюсь, что это поможет кому-то
Ответ 14
Попробуйте это.
function getData($name, $limit = NULL, $page = '1') {
if (!$limit){
$limit = 50;
}
}
getData('some name', '', '23');
Ответ 15
Вы не можете пропустить средний параметр в вызове функции. Но вы можете работать с этим:
function_call('1', '2', '3'); // Pass with parameter.
function_call('1', null, '3'); // Pass without parameter.
Функции:
function function_call($a, $b='50', $c){
if(isset($b)){
echo $b;
}
else{
echo '50';
}
}
Ответ 16
Как отметил @IbrahimLawal. Лучше всего установить только значения null
. Просто проверьте, прошло ли значение null
, в котором вы используете свои установленные значения по умолчанию.
<?php
define('DEFAULT_LIMIT', 50);
define('DEFAULT_PAGE', 1);
function getData($name, $limit = null, $page = null) {
$limit = is_null($limit) ? DEFAULT_LIMIT : $limit;
$page = is_null($page) ? DEFAULT_PAGE : $page;
...
}
?>
Надеюсь, что это поможет.
Ответ 17
getData('some name');
просто не передают их, и значение по умолчанию будет принято