Não é possível usar o valor de retorno do método no contexto de gravação

465

Eu acho que o seguinte trecho de código deve funcionar, mas não funciona (Editado: Agora funciona no PHP 5.5+) :

if (!empty($r->getError()))

Onde getError()é simplesmente:

public function getError()
{
    return $this->error;
}

No entanto, acabo com este erro:

não é possível usar o valor de retorno do método no contexto de gravação

O que isto significa? Isso não é apenas uma leitura?

Extrakun
fonte
2
Provavelmente em PHP 5.5 será permitida a passagem expressões para empty: wiki.php.net/rfc/empty_isset_exprs
Carlos Campderrós
Ok, acho a resposta do porneL correta também, este meu código if ( !$e->find('div') ) que verifica se o elemento HTML DOM atual está vazio ou não. Eu o uso dentro do loop para imprimir apenas uma única Div sem a Div interna dentro dela.
Salem

Respostas:

769

empty() precisa acessar o valor por referência (para verificar se essa referência aponta para algo que existe), e o PHP anterior ao 5.5 não suportava referências a valores temporários retornados de funções.

No entanto, o verdadeiro problema que você tem é que você usa empty(), acreditando equivocadamente que o valor "vazio" é diferente de "falso".

Vazio é apenas um apelido para !isset($thing) || !$thing. Quando a coisa que você está verificando sempre existe (nos resultados PHP das chamadas de função sempre existem), a empty()função não passa de um operador de negação .

PHP não tem conceito de vazio . Valores que avaliam como falso estão vazios, valores que avaliam como verdadeiro são não vazios. É a mesma coisa. Este código:

$x = something();
if (empty($x)) 

e isto:

$x = something();
if (!$x) 

sempre tem o mesmo resultado, em todos os casos, para todos os tipos de dados (porque $xdefinido empty()é redundante).

O valor de retorno do método sempre existe (mesmo que você não tenha uma returninstrução, o valor de retorno existe e contém null). Portanto:

if (!empty($r->getError()))

é logicamente equivalente a:

if ($r->getError())
Kornel
fonte
29
Essa é uma resposta muito melhor do que a selecionada atualmente.
SystemParadox
20
@gcb: no, o manual do PHP diz explicitamente que é idêntico: "empty () é o oposto de (boolean) var, exceto que nenhum aviso é gerado quando a variável não está definida".
Kornel
16
A parte que não gera uma advertência é muito importante ... vazio ($ var) retornará verdadeiro se for 0, '', array (), NULL ou nem definido. É uma boa prática, especialmente para que você possa registrar suas reais advertências sem os arquivos encher
landons
3
Ok, ótima resposta, mas qual é o caminho certo para evitar isso, alguém sabe?
Javatar
3
@EugenMihailescu em geral, que é ok, mas não é estritamente equivalente a esvaziar (), porque "", 0, etc, são "vazio", mas não nulo.
Kornel
330

Nota: Esta é uma resposta votada muito alta com alta visibilidade, mas observe que ela promove práticas de codificação ruins e desnecessárias! Veja a resposta de @ Kornel para a maneira correta.

Nota 2: eu apoio as sugestões para usar a resposta do @ Kornel . Quando escrevi essa resposta há três anos, pretendi apenas explicar a natureza do erro, não necessariamente endossar a alternativa. O snippet de código abaixo não é recomendado.


É uma limitação de empty () nas versões do PHP abaixo de 5.5.

Nota: empty () apenas verifica variáveis, pois qualquer outra coisa resultará em um erro de análise. Em outras palavras, o seguinte não funcionará: vazio (trim ($ name)).

Você teria que mudar para isso

// Not recommended, just illustrates the issue
$err = $r->getError();
if (!empty($err))
Peter Bailey
fonte
156
Isso é insanamente contraproducente.
David Murdoch
47
Nota: O mesmo acontece com isset(). ou seja: isset($this->foo->getBar())resultará no mesmo problema.
catchdave
7
A resposta de porneL explica isso em mais detalhe, com uma solução melhor
SystemParadox
5
@ SystemParadox - Depende do que você quer dizer com "melhor". a resposta de porneL é indiscutivelmente mais completa com uma solução "mais limpa", mas também não explica a origem do erro.
Peter Bailey
4
Porque não está errado, @ deceze. Não é a melhor resposta, você não terá nenhum argumento meu lá. Até votei em mim mesmo. É uma resposta muito antiga, mas não está errada . Quanto aos altos votos: lembre-se, os números chegaram quase 17 meses depois desse.
Peter Bailey
37

De acordo com os documentos do PHP :

empty () apenas verifica variáveis, pois qualquer outra coisa resultará em um erro de análise

Você não pode usar empty()diretamente no valor de retorno de uma função. Em vez disso, defina o retorno de getError()como uma variável e execute empty()a variável.

George Claghorn
fonte
19

Eu costumo criar uma função global chamada is_empty () apenas para contornar esse problema

function is_empty($var)
{ 
 return empty($var);
}

Então, em qualquer lugar que eu normalmente usaria empty (), apenas uso is_empty ()

Luke PM
fonte
2
É melhor não fazer isso e seguir os padrões (por mais irritantes que possam ser).
tonyhb
1
@dynamism você poderia explicar por que não?
Janis Veinbergs
1
Porque as funções de conveniência podem ser uma dificuldade para ler no código de outra pessoa. Além disso, em uma arquitetura MVC / HMVC, pode atrapalhar sua estrutura. No final do dia, os codificadores PHP devem saber suas limitações e entender pequenas soluções alternativas sem as funções de conveniência.
tonyhb
14
Uau, você acabou de inventar uma função de negação . Você sabe que o PHP tem !operador para isso? :)
Kornel 4/11
4

Como apontado por outros, é uma limitação (estranha) de vazio ().

Para a maioria das finalidades, fazer isso é igual a chamar vazio, mas funciona:

if ($r->getError() != '')
Jani Hartikainen
fonte
5
Isso não é verdade - empty()abrange muitas mais possibilidades do que apenas uma cadeia em branco
Robbie Averill
3
É por isso que ele diz que "para a maioria dos fins ", não todos
Jani Hartikainen
2

O problema é esse, você deseja saber se o erro não está vazio.

public function getError() {
    return $this->error;
}

Adicionar um método isErrorSet () resolverá o problema.

public function isErrorSet() {
    if (isset($this->error) && !empty($this->error)) {
        return true;
    } else {
        return false;
    }
}

Agora isso funcionará bem com este código sem aviso prévio.

if (!($x->isErrorSet())) {
    echo $x->getError();
}
Jean Carlo Bambalan
fonte
-3

A maneira alternativa de verificar se uma matriz está vazia pode ser:

count($array)>0

Funciona para mim sem esse erro

quardas
fonte