Как пропустить необязательные аргументы в вызове функции?

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');

просто не передают их, и значение по умолчанию будет принято