Подтвердить что ты не робот

Возврат NULL с декларациями возвращаемого типа

Я рефакторизую базу кода для использования с PHP7, в частности, используя подсказки скалярного типа и подсказки возвращаемого типа, когда я столкнулся с проблемой.

У меня есть класс с некоторыми свойствами, один из которых - id. Этот идентификатор не является обязательным (вы можете создать объект без установки id). При создании нового объекта этого класса вы не устанавливаете id, и он получает идентификатор, как только он вставлен в db (отдельным классом сопоставления).

Этот класс сопоставления должен проверить, существует ли объект в db, и он делает это, проверяя, установлен ли идентификатор:

if(empty($exampleObject->getId())) {
    // Insert object
} else {
    // Update object
}

Я применял подсказки возвращаемого типа к каждой функции в моей кодовой базе, и проблема в том, что функция getId() не может вернуть NULL, если я применяю тип возвращаемого типа. Это TypeErrors, даже без строгой настройки:

Неустранимая ошибка: Uncaught TypeError: возвращаемое значение ExampleClass:: getId() должно быть типа integer, null возвращено

Я считал, что не задавать подсказку типа возврата для этого getter, но я понял, что проблема, вероятно, не является намеком на возвращаемый тип, а тем фактом, что я использую смешанные типы возвращаемых данных. Я помню, где-то читал, что использование смешанных типов возврата - это плохо, но я не уверен, как справиться с этим, не используя смешанные типы возврата. Я мог:

  • Выбросьте исключение в getter и создайте чек в классе mapper, чтобы он поймал это исключение.
  • Поймать исключение TypeError и использовать это, чтобы указать, что идентификатор не установлен.
  • Сделать свойство id общедоступным, поэтому я могу напрямую вызвать isset.
  • Добавить другой метод hasId() return isset($this->id)

Честно говоря, мне не очень нравится какое-либо из этих решений, и мне было интересно, есть ли лучший вариант. Какая наилучшая практика для подобных случаев?

Кроме того, не должен ли я получать TypeError только в том случае, если включен строгий ввод? Я думал, что PHP7 по умолчанию "подсказки слабых типов".

4b9b3361

Ответ 1

PHP 7.1 добавил типы с нулевым значением, где вы помещаете вопросительный знак перед именем типа, чтобы пометить возвращаемый тип как принимающий оба типа и null:

public function getId(): ?int {
    /* … */
}

Если вы все еще на PHP 7.0, я предлагаю отказаться от объявления типа и использовать docblock.

Ответ 2

Использование null означает использование объектно-ориентированных подходов, поскольку типы значений не могут быть нулевыми. Поэтому было бы полезно использовать оболочку класса для целочисленного типа. Например, SplInt из типов SPL.