Как PHP 7 возвращает приведение типа к нулю? - PullRequest
3 голосов
/ 21 марта 2019

В соответствии с PHP документацией для деклараций типа возврата (выделено мое):

.... В слабом режиме по умолчанию возвращаемые значения будут приводиться к правильному типу, если они уже не относятся к этому типу .

Это означает, что метод returnInt()

class A {
    public function returnInt(): int {
        return "6a";
    }
}

вернет значение int 6 (как и должно быть).

Однако, возвращая null из функции, приведенной выше, выдается ошибка TypeError, даже если null может быть легко приведен к целому числу 0 с помощью (int) null

FATAL ERROR Uncaught TypeError: Возвращаемое значение A :: returnInt () должно иметь тип integer, возвращается ноль

Почему это не будет работать для нулевых значений?

Какую логику использует PHP при попытке приведения типов?

Ответы [ 2 ]

4 голосов
/ 21 марта 2019

Это ожидается и по замыслу.Вы можете найти оригинальный RFC для этой функции в http://wiki.php.net/rfc/return_types.

В частности, есть раздел Disallowing NULL on Return Types, в котором говорится:

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

  1. Это соответствует текущему поведению типа параметра.Когда параметры имеют объявленный тип, значение null не допускается.
  2. Разрешение null по умолчанию работает против цели объявления типа.Объявления типов упрощают анализ окружающего кода.Если бы ноль был разрешен, программисту всегда приходилось бы беспокоиться о нулевом регистре.

Теперь я не вижу в этом rfc каких-либо разговоров о преобразовании типов, тогда как официальные документытаким образом, шансы на то, что ноль не конвертируется просто потому, что RFC явно сказал, что это не сработает.Лично я думаю, что оставлять ноль как нечетное странно.Потенциально это также рассматривалось как связанное с обнуляемыми типами rfc, что могло повлиять на то, как было определено, что null работает.

Не могу сказать, что лично согласен с тем, как это работает, но яя не разработчик ядра:).

2 голосов
/ 21 марта 2019

Правило при отсутствии возврата null при объявлении типизированных возвращаемых значений заменяет правило о приведении возвращаемых значений к объявленному типу.

Самый важный бит это:

Это соответствует текущему поведению типа параметра. Когда для параметров объявлен тип, значение null не допускается

Если ваша функция или метод ожидает ненулевое значение int в качестве параметра, вы не можете передать нулевое значение и ожидать его принудительного приведения, но вы можете, например, передать строку или логическое значение.

* 1016 Е.Г. *

function foo (int $bar) {
    echo "Received: ", $bar, "\n";
}

foo("1");
foo(false);
foo(null);

Первые два будут работать, , но последние не будут .

RFC решил согласовать с этим ожиданием для согласованности.

Ваш выбор очевиден, либо возвращайте обнуляемое целое число:

function foo(): ?int {
   return null;
}

Или, если это нежелательно, просто приведите возвращаемое значение перед отправкой обратно:

function foo(): int {
   return (int) null;
}
...