Tipos de retorno anuláveis ​​no PHP7

159

O PHP 7 introduz declarações de tipo de retorno . O que significa que agora posso indicar que o valor de retorno é uma determinada classe, interface, matriz, que pode ser chamada ou um dos tipos escalares recém-sugeridos, como é possível para os parâmetros de função.

function returnHello(): string {
    return 'hello';
}

Muitas vezes, acontece que um valor nem sempre está presente e você pode retornar algo de algum tipo ou nulo. Embora você possa tornar os parâmetros anuláveis ​​configurando seu padrão como null ( DateTime $time = null), não parece haver uma maneira de fazer isso para os tipos de retorno. É esse mesmo o caso, ou não estou descobrindo como fazê-lo? Estes não funcionam:

function returnHello(): string? {
    return 'hello';
}

function returnHello(): string|null {
    return 'hello';
}
Jeroen De Dauw
fonte
8
O PHP7 ainda não permitirá tipos de retorno anuláveis, mas há um RFC que visa resolver isso no PHP 7.1 aqui . A notação propesed seria entãofunction returnString(?string $stringNull) : ?string { return $stringNull;}
Elias Van Ootegem
1
Acabei emulando a nulidade, abusando de exceções no meu aplicativo por enquanto. Se você está bem com sendo boba, bem, isso pode ser de uso: github.com/JeroenDeDauw/OhMyPhp/blob/master/src/...
Jeroen De Dauw
Talvez pode fazer mais sentido usar o PHP7 Trowablede interface (especificamente, estendendo-se o TypeError)
Elias Van Ootegem

Respostas:

258

O PHP 7.1 agora suporta tipos de retorno anuláveis . O primeiro RFC ao qual vinculei foi o que eles procuraram:

function nullOrString(int $foo) : ?string
{
    return $foo%2 ? "odd" : null;
}

resposta antiga:

Como meu comentário foi na verdade uma resposta para a pergunta:

O PHP 7 ainda não suporta tipos de retorno anuláveis, mas há uma RFC para resolver exatamente isso, que visa pousar no PHP 7.1. Se for aprovada, a sintaxe afetará todas as dicas de tipo (tipos de retorno e dicas de tipo):

public function returnStringOrNull(?array $optionalArray) : ?string
{
    if ($optionalArray) {
        return implode(', ', $optionalArray);//string returned here
    }
    return null;
}

Há também uma RFC concorrente para adicionar tipos de união, que poderiam fazer a mesma coisa, mas pareceriam diferentes:

public function returnStringOrNull(array|null $optionalArray) : string|null
{
    if ($optionalArray) {
        return implode(', ', $optionalArray);//string returned here
    }
    return null;
}

Por enquanto, porém, você terá que escrever:

public function returnStringOrNull( array $optionalArray = null)
{
    if ($optionalArray) {
        return implode(', ', $optionalArray);
    }
}

Ou simplesmente retorne uma string vazia para ser consistente com o tipo de retorno e verifique o valor falso:

public function returnStringOrNull( array $optionalArray = null) : string
{
    if ($optionalArray) {
        return implode(', ', $optionalArray);
    }
    return '';
}
//call
$string = $x->returnStringOrNull();
if (!$string) {
    $string = $x->returnStringOrNull(range(1, 10));
}
Elias Van Ootegem
fonte
5
PHP 7 won't support nullable return-types just yet, but there's an RFC out to address just that- sim, RFC, "ainda". Não me entenda mal - eu sou muito usuário de PHP desde tempos muito ruins até agora, sem brechas, mas quando vi todos esses RFCs que eles rejeitaram por 7, minha impressão foi apenas "WTF ?!". Os usuários veem a bagunça e estão dispostos a limpá-la da maneira compatível com versões anteriores , e eles simplesmente ficam "não". Métodos limpos nomeando bagunça? Corrigido nullnão ser cidadão muito especial? Não, não é necessário. Adicionar opção para diferenciar maiúsculas de minúsculas? Nah .. E então, surpreenda que as pessoas mudem.
Marcin Orlowski
1
@ MarcinOrlowski: Uma dica de tipo de retorno anulável faria sentido. Eu segui algumas das RFCs por 7, e concordei em grande parte com elas rejeitando muitas delas. As mudanças nas quais eles estavam focados não eram tanto o idioma, mas o tempo de execução e o compilador. Para algumas das RFCs que foram recusadas, vale a pena ler os tópicos de discussão para entender por que eles escolheram não implementar essas alterações (por exemplo, descontinuadas var). O que é uma pena é que em vez disso, aceitou um demasiados agradável de se ter de (operador de nave espacial, por exemplo)
Elias Van Ootegem
Os tipos anuláveis ​​do @EliasVanOotegem agora são suportados corretamente, pois o 7.1 foi lançado em 1º de dezembro.
Loneomeday
@lonesomeday: Na verdade ele faz, acrescentou o link + exemplo básico para o fundo da minha resposta
Elias Van Ootegem
mmm ish é um bom tipo para atualizar esta resposta! ou seja, o tipo de união não parece ser suportado no PHP 7.1
Dennis
67

Tipos anuláveis estão disponíveis no PHP 7.1.

Este é um exemplo de sintaxe:

public function getName(): ?string
{
    return $this->name; // name can be null
}

Agora o PHP 7.1 é GA e você pode atualizar do PHP 7.0 (existem apenas algumas alterações incompatíveis com versões anteriores que você precisa verificar)

the_nuts
fonte
22
Na IMO, é uma piada entregar declarações de tipo de retorno sem implementar "anulável". Os tipos de retorno não podem ser usados ​​até que o recurso "anulável" seja implementado.
joonas.fi
2
@ joonas.fi Os valores de retorno estritamente digitados da IMO sempre devem ser desse tipo, um retorno nulo não se aplica a esse contrato e, em vez disso, gera uma exceção, dando mais significado ao motivo de um valor nulo.
Steve Buzonas
8
@SteveBuzonas, se você considerar um método getAgeInYears () em um objeto que representa uma Pessoa, como você modelaria uma pessoa que não nos informou sua idade? Retornar nulo? Retornar 0? Retornar nulo semanticamente significa "não sabemos", enquanto 0 significa semanticamente "a pessoa tem 0 anos". Portanto, eu diria que getAgeInYears ():? Int é o melhor design. Lançar exceções deve ser reservada para casos bem ... excepcionais. Não conhecer a idade de uma pessoa na maioria dos sistemas não deve ser considerado um caso excepcional.
joonas.fi
@ joonas.fi verdade, e isso é uma prática comum. No entanto, sua implementação agora precisa estar ciente de que o campo é anulável e é explicitamente manipulado de acordo. Que pode muito bem ser x, exceto quando nulo, que pode ser implementado com a mesma facilidade com uma tentativa / captura. Além disso, se alguém realmente exigir um valor nesse campo anulável para continuar a execução, uma exceção provavelmente será uma opção melhor.
Steve Buzonas
Percebi que essa sintaxe faz com que o PHPMD gere muitos erros. Espero que eles consertem isso em breve.
precisa
0

Funciona com qualquer tipo.
Exemplo:

public function getOpportunity(): ?Opportunity
{
    return $this->opportunity;
}
Bayma Bruno
fonte