Я реорганизовал кодовую базу для использования с PHP7, особенно реализуя подсказки скалярного типа и подсказки возвращаемого типа, когда столкнулся с проблемой.
У меня есть класс с некоторыми свойствами, одним из которых является идентификатор. Этот идентификатор не является обязательным (вы можете создать объект без установки идентификатора). При создании нового объекта этого класса вы не устанавливаете идентификатор, и он получает идентификатор, как только он вставлен в БД (отдельным классом mapper).
Этот класс mapper должен проверить, существует ли объект в БД, и он делает это, проверяя, установлен ли id:
if(empty($exampleObject->getId())) {
// Insert object
} else {
// Update object
}
Я применял подсказки типа возврата к каждой функции в моей кодовой базе, и проблема в том, что функция getId()
не могу вернуться НОЛЬ если я приведу в исполнение ИНТ тип возврата. Это TypeErrors, даже без строгой типизации:
Фатальная ошибка: Uncaught TypeError: Возвращаемое значение ExampleClass :: getId () должно иметь тип integer, возвращается ноль
Я решил не устанавливать подсказку типа возврата для этого метода получения, но потом понял, что проблема, вероятно, не в подсказке типа возврата, а в том, что я использую смешанные типы возврата. Я помню, как читал где-то, что использование смешанных типов возврата — это плохо, но я не уверен, как справиться с этим без использования смешанных типов возврата. Я мог бы:
hasId() return isset($this->id)
Честно говоря, мне не очень нравятся эти решения, и мне было интересно, есть ли лучший вариант. Какова лучшая практика для подобных случаев?
Кроме того, я не должен получить TypeError, только если у меня включена строгая типизация? Я думал, что PHP7 по умолчанию «слабые подсказки типа».
PHP 7.1 добавлен обнуляемые типы, где вы ставите вопросительный знак перед именем типа, чтобы пометить возвращаемый тип как принимающий как этот тип, так и ноль:
public function getId(): ?int {
/* … */
}
Если вы все еще на PHP 7.0, я предлагаю опустить объявление типа и использовать docblock.
С помощью null
означает использование объектно-ориентированных подходов, потому что типы значений не могут быть нулевыми. Так что может быть полезно использовать обертку класса вокруг целочисленного типа. Например, лубок из типов SPL.