it-swarm.com.ru

Возврат NULL с объявлениями возвращаемого типа

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

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

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

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

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

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

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

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

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

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

15
Compizfox

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

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

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

24
Andrea

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

0
max