Решение с именованными параметрами в PHP 7+

Как я могу реализовать функцию именованного аргумента в PHP 7+?

Идеальный синтаксис:

find($wildcard, relative = true, listIfEmpty = false) {
    ...
}

Но такого решения нет. В ответ я реализовал кратчайшее возможное решение, поддерживающее:

  • Рефакторинг
  • Введите подсказки для параметров и результата функции
  • Многоразовый набор параметров
  • Типобезопасные параметры
  • Значения по умолчанию для параметров
  • Getter для каждого параметра (без жестко закодированной строки)
  • Очень простой сеттер/геттер, в котором вы меняете только одно имя для каждого параметра.

Дополнительную информацию и реализацию см. в ответе


person Behnam    schedule 02.06.2019    source источник
comment
Возможный дубликат именованных параметров функции в PHP   -  person miken32    schedule 21.08.2019
comment
@ miken32 Вы видите, что это вопрос/ответ от меня?!   -  person Behnam    schedule 22.08.2019
comment
да. Вопрос дублируется и должен быть удален. Ответ должен быть опубликован как ответ на другой вопрос.   -  person miken32    schedule 22.08.2019
comment
Это очень плохо, что вместо того, чтобы голосовать за полный ответ и предоставленную техническую информацию, вы придерживаетесь деталей управления вопросами.   -  person Behnam    schedule 23.08.2019
comment
Для PHP8+ существует встроенное решение: stackoverflow.com/a/64072408/7082164   -  person Jsowa    schedule 26.09.2020
comment
Что точно вы ищете? Данный код не похож на корректный код, который будет компилироваться с использованием PHP 7.   -  person Nico Haase    schedule 20.02.2021


Ответы (2)



Во-первых, сделайте это один раз в своем фреймворке или глобально:

// the superclass that every params class will extend this
class params {
  protected function setter($key, $value) {
    if ($value === null) {
      return $this->{$key};
    }

    $this->{$key} = $value;
    return $this;
  }
}

Затем сделайте это для каждой функции, которая требует именованных аргументов с собственными именами:

// define a helper method for simple instantiation
function params_find() { return new params_find(); }

// a params class that will use from find() method
class params_find extends params {

  // list of params with default values
  // below list is just a sample
  protected $listIfEmpty   = false;
  protected $structured    = true;
  protected $relative      = false;
  protected $prefix        = "";
  protected $justFileNames = false;

  // for each param duplicate line and just change function name exactly matching param name. setter/getter will done automatically
  function listIfEmpty($val = null)   { return $this->setter(__FUNCTION__, $val); }
  function structured($val = null)    { return $this->setter(__FUNCTION__, $val); }
  function relative($val = null)      { return $this->setter(__FUNCTION__, $val); }
  function prefix($val = null)        { return $this->setter(__FUNCTION__, $val); }
  function justFileNames($val = null) { return $this->setter(__FUNCTION__, $val); }
}

После этого напишите свою функцию, используя эту функцию:

// your function that uses named arguments
// in this example $wildcard argument is required
function find($wildcard = [], params_find $opt = null) {
  if ($opt === null) {
    $opt = params_find();
  }

  // do something with your params like this
  if ($opt->structured()) {
    // ...
  }

  return $something_if_you_want;
}

Наконец, используйте его с простейшим интерфейсом:

// finally use your function with some params ( other params will have default values )
$files = find("*.css", params_find()
  ->structured(false)
  ->listIfEmpty(true)
  ->prefix("something")
);


// if you need all default values
$files = find("*.css");


// reusable options
$opt = params_find()
  ->listIfEmpty(false)
  ->prefix("something")
)
$files1 = find("*.css", $opt);
$files2 = find("*.html", $opt);
$files3 = find("*.scss", $opt
  ->structured(true)
);
person Behnam    schedule 02.06.2019
comment
Пожалуйста, поделитесь более подробной информацией - где вы используете именованные параметры в данном коде? params_find() ->structured(false) выглядит совсем иначе - person Nico Haase; 20.02.2021