No se puede usar el valor de retorno del método en el contexto de escritura

465

Creo que el siguiente fragmento de código debería funcionar, pero no funciona (Editado: ahora funciona en PHP 5.5+) :

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

Donde getError()es simplemente:

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

Sin embargo, termino con este error:

no se puede usar el valor de retorno del método en el contexto de escritura

¿Qué significa esto? ¿No es esto solo una lectura?

Extrakun
fuente
2
Probablemente en PHP 5.5 se le permitirá pasar expresiones a empty: wiki.php.net/rfc/empty_isset_exprs
Carlos Campderrós
Ok, encuentro que la respuesta de porneL también es correcta en mi código if ( !$e->find('div') ) que comprueba si el elemento DOM HTML actual está vacío o no. Lo uso dentro del bucle para imprimir solo un Div sin Div interno dentro de él.
Salem

Respuestas:

769

empty() necesita acceder al valor por referencia (para verificar si esa referencia apunta a algo que existe), y PHP antes de 5.5 no admitía referencias a valores temporales devueltos por funciones.

Sin embargo, el verdadero problema que tiene es que lo usa empty()en absoluto, creyendo erróneamente que el valor "vacío" es diferente de "falso".

Vacío es solo un alias para !isset($thing) || !$thing. Cuando lo que está comprobando siempre existe (en PHP los resultados de las llamadas a funciones siempre existen), la empty()función no es más que un operador de negación .

PHP no tiene el concepto de vacío . Los valores que evalúan a falso están vacíos, los valores que evalúan a verdadero no están vacíos. Es lo mismo. Este código:

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

y esto:

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

siempre tiene el mismo resultado, en todos los casos, para todos los tipos de datos (porque $xestá definido empty()es redundante).

El valor de retorno del método siempre existe (incluso si no tiene una returndeclaración, el valor de retorno existe y contiene null). Por lo tanto:

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

es lógicamente equivalente a:

if ($r->getError())
Kornel
fuente
29
Esta es una respuesta mucho mejor que la seleccionada actualmente.
SystemParadox
20
@gcb: no, el manual de PHP dice explícitamente que es idéntico: "vacío () es lo opuesto a (boolean) var, excepto que no se genera ninguna advertencia cuando no se establece la variable".
Kornel
16
La no generación de una parte de advertencia es bastante importante ... vacío ($ var) devolverá verdadero si es 0 '', array (), NULL o ni siquiera está definido. Es una buena práctica, sobre todo por lo que puede registrar sus verdaderas advertencias sin los archivos llenando
Landons
3
Ok, gran respuesta, pero ¿cuál es la forma correcta de evitar esto? ¿Alguien sabe?
Javatar
3
@EugenMihailescu en general, que está bien, pero no es estrictamente equivalente a vaciar (), porque "", 0, etc. son "vacío", pero no nula.
Kornel
330

Nota: Esta es una respuesta muy votada con una alta visibilidad, pero tenga en cuenta que promueve prácticas de codificación innecesarias. Ver la respuesta de @ Kornel para la forma correcta.

Nota # 2: Respaldo las sugerencias para usar la respuesta de @ Kornel . Cuando escribí esta respuesta hace tres años, solo tenía la intención de explicar la naturaleza del error, no necesariamente respaldar la alternativa. No se recomienda el siguiente fragmento de código.


Es una limitación de empty () en versiones de PHP inferiores a 5.5.

Nota: empty () solo verifica las variables, ya que cualquier otra cosa dará como resultado un error de análisis. En otras palabras, lo siguiente no funcionará: vacío (recortar ($ nombre)).

Tendrías que cambiar a esto

// Not recommended, just illustrates the issue
$err = $r->getError();
if (!empty($err))
Peter Bailey
fuente
156
Esto es increíblemente contraproducente.
David Murdoch
47
Nota: Lo mismo es cierto con isset(). es decir: isset($this->foo->getBar())dará como resultado el mismo problema.
catchdave
77
La respuesta de porneL explica esto con más detalle, con una mejor solución
SystemParadox
55
@SystemParadox - Depende de lo que quieras decir con "mejor". La respuesta de porneL es posiblemente más exhaustiva con una solución "más limpia", pero tampoco explica el origen del error.
Peter Bailey
44
Porque no está mal, @deceze. No es la mejor respuesta, no tendrás ninguna discusión de mí allí. Incluso voté por mi cuenta. Es una respuesta muy antigua pero no está mal . Con respecto a los votos altos: recuerde, los porneL llegaron casi 17 meses después de este.
Peter Bailey
37

De acuerdo con los documentos PHP :

empty () solo verifica las variables, ya que cualquier otra cosa dará como resultado un error de análisis

No se puede usar empty()directamente en el valor de retorno de una función. En su lugar, establezca el retorno desde getError()a una variable y ejecútelo empty()en la variable.

George Claghorn
fuente
19

Por lo general, creo una función global llamada is_empty () solo para solucionar este problema

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

Luego, en cualquier lugar donde normalmente hubiera usado empty (), solo uso is_empty ()

Luke PM
fuente
2
Es mejor no hacer esto y cumplir con los estándares (por más molestos que puedan ser).
tonyhb
1
@ dinamismo ¿podrías explicar por qué no?
Janis Veinbergs
1
Porque las funciones de conveniencia pueden ser difíciles de leer en el código de otra persona. Además, en una arquitectura MVC / HMVC puede alterar su estructura. Al final del día, los codificadores de PHP deben saber sus limitaciones y ser capaces de comprender pequeñas soluciones sin funciones de conveniencia.
tonyhb
14
Wow, acabas de inventar una función de negación . ¿Sabes que PHP tiene !operador para esto? :)
Kornel
4

Como señalaron otros, es una limitación (extraña) de empty ().

Para la mayoría de los purproses, hacer esto es igual a llamar a empty, pero esto funciona:

if ($r->getError() != '')
Jani Hartikainen
fuente
55
Esto no es cierto - empty()cubre muchas más posibilidades que solo una cadena en blanco
Robbie Averill
3
Es por eso que dice "para la mayoría de los propósitos ", no todos
Jani Hartikainen
2

El problema es este, desea saber si el error no está vacío.

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

Agregar un método isErrorSet () resolverá el problema.

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

Ahora esto funcionará bien con este código sin previo aviso.

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

La forma alternativa de verificar si una matriz está vacía podría ser:

count($array)>0

Funciona para mí sin ese error

quardas
fuente