Когда следует использовать NULL в типах и докблоках типа PHPDoc?

Я смущен тем, когда использовать null как тип при описании переменных с помощью PHPDoc. Предполагают ли типы намеки, чтобы описать надежды и ожидания для внешних абонентов, чтобы их предвидеть и соблюдать, или они должны документировать все возможные типы переменных, даже если надежда на то, что это будет один очень специфический тип на практике?

Пример 1: значения по умолчанию. Следующая функция ожидает только ненулевые значения. Но если значение не передано, оно по умолчанию равно null и явно проверяет его как способ определить, было ли передано или нет, и возвращает специальное значение для этого случая. Надеюсь, никакой внешний вызывающий абонент не передаст ничего, кроме целого. Должен ли null использоваться в типе @param, как указано ниже, или должен указывать только int, так как это то, что мы хотим передать, если что-либо передано?

/**
 * @param int|null $bar
 */
function foo($bar = null) {
  if(is_null($bar)) { 
    return 'ABC';
  }

  return doSomething($bar);
}

Пример 2: свойства экземпляра. Мы хотим, чтобы $bar содержал целые числа. Тем не менее, если для бара ничего не установлено, значение PHP по умолчанию для этого свойства экземпляра равно null. Нужно ли мне учитывать это в каждом месте, где используется $bar, с возможным нулевым типом, как показано ниже?

class Foo {
  /**
   * @var int|null
   */
  public $bar;

  /**
   * @param int|null $bar
   */
  public setBar( $bar) {
    $this->bar = $bar;
  }

  /**
   * @return int|null
   */
  public function getBar() {
    return $this->bar;
  }
}

В основном, я нахожу, что улавливаю почти каждое объявление @param и @var с помощью |null, потому что технически это может быть это значение. Но на практике этого не должно быть. Должен ли я ожидать, что почти все мои типы будут содержать возможность null или это должно быть принято, и я должен избегать указания его, если я не ожидаю установить или получить значение null явно?

Ответ 1

На практике я склоняюсь к тому, чтобы иметь теги param, которые перечисляют только то, что вы хотите передать. Однако для возвращаемых тегов вам действительно нужно перечислять все типы, которые можно было бы вернуть. Вот почему я различаюсь на двух.

Так как PHP не сильно типизирован, даже когда вы говорите "только проход в int", ваш метод все равно должен удостовериться, что он не передал что-то неожиданное. Просто потому, что код метода пытается обрабатывать прием других типов, вы не хотите, чтобы ваши документы говорили вашим пользователям "конечно, вы можете передать мне NULL, и я сделаю с ним что-нибудь для вас". Вы хотите, чтобы ваши документы говорили "дайте мне int, period".

При рассмотрении возвращаемых значений вашим пользователям действительно действительно нужно знать каждый потенциальный тип возвращаемого результата, который может вернуться из вашего метода, потому что им действительно нужно покрыть свои базы в своем коде, чтобы обрабатывать все типы, которые может вернуть ваш метод.

Ответ 2

Да, по стандартам PHPDoc, вы должны включать null везде (если это применимо, конечно)

Смотрите здесь: http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_tags.param.pkg.html

Тип данных должен быть допустимым типом PHP (int, string, bool и т.д.), a имя класса для типа объекта или просто "смешанный". Кроме того, вы можете перечислите несколько типов данных для одного параметра, разделив их на (например, "@param int | string $p1" ). Вы можете документировать параметры перечисленные или любые дополнительные параметры, которые будут обрабатываться стандартным PHP функции func_num_args()/get_func_arg(). Рекомендуемый формат имени для параметры, перечисленные в func_get_arg(), равны:     $ paramname, если есть только один параметр     $ paramname,... если количество параметров не ограничено