Несколько возвращаемых типов php 7
У меня есть несколько методов, которые могут возвращать один из двух типов возврата - (я использую фреймворк с использованием MCV, поэтому рефакторинг этих нескольких функций, в частности, не привлекателен)
Можно ли объявить возвращаемый тип, возвращающий один или другой, и не выполнить что-либо еще?
function test(): ?
{
if ($this->condition === false) {
return FailObject;
}
return SucceedObject;
}
Ответы
Ответ 1
На данный момент поддерживаемый способ состоит в том, чтобы два объекта совместно использовали интерфейс. Пример:
interface ReturnInterface {}
class FailObject implements ReturnInterface {}
class SuccessObject implements ReturnInterface {}
function test(): ReturnInterface {}
В этом примере ReturnInterface
пусто. Его простое присутствие поддерживает необходимое объявление типа возвращаемого значения.
В настоящее время сообщество внутренностей PHP обсуждает типы объединений. Если текущее предложение будет принято, PHP 8+ будет поддерживать несколько типов возврата:
function test(): FailObject|SuccessObject {}
Однако более ранний RFC объединения был отклонен.
Я предпочитаю подход интерфейса независимо от типов объединения. Для меня это более понятно и более расширяемо. Если позже мне понадобится WarnObject
, мне просто нужно определить его как расширение ReturnInterface
, а не просматривать все подписи и обновлять их до FailObject|SuccessObject|WarnObject
.
Ответ 2
Как отмечено епископом, существует RFC для добавления нескольких типов возврата. Тем не менее, я думал, что добавлю, что с PHP7.1 теперь вы можете указать тип возвращаемого значения типа null:
function exampleFunction(string $input) : ?int
{
// Do something
}
Таким образом, эта функция примет строку и добавив вопросительный знак до того, как вы разрешите ему возвращать нуль или целое число.
Здесь ссылка на документацию:
http://php.net/manual/en/functions.returning-values.php
И вот цитата с этой страницы, объясняющая использование:
PHP 7.1 допускает типы void и null return, предшествующие объявлению типа с помощью? - (например, функция canReturnNullorString():? String)
Кроме того, вот еще один поток, который относится к этому: Нулевые типы возвращаемых данных в PHP7
Ответ 3
PHP начиная с 7.2 поддерживает тип возвращаемого объекта
http://php.net/manual/en/migration72.new-features.php
function test(object $obj) : object
// return any type of object ...
Ответ 4
Это неверный путь:
function test(): ?
{
if ($this->condition === false) {
return FailObject;
}
return SucceedObject;
}
Несколько типов возврата - плохая практика. Хорошие практики:
Вы должны определить исключение:
class FailObjectException extends \Exception
{
private $exampleExtraInfo;
public function __construct($exampleExtraInfo, $message)
{
parent::__construct($message);
$this->exampleExtraInfo = $exampleExtraInfo;
}
public function exampleExtraInfo(): int
{
return $this->exampleExtraInfo;
}
}
Теперь вы можете определить функцию как:
function test(): SucceedObject
{
if ($this->condition === false) {
throw new FailObjectException(...,...);
}
return SucceedObject;
}
И используйте эту функцию с try/catch:
try{
$succeedObject = $any->test();
} catch (FailObjectException $exception){
//do something
}