2010-03-01 21 views
78
$el = array_shift($instance->find(..)) 

El código anterior de alguna manera los informes de la estricta advertencia estándares, pero esto no será:normas estrictas: Sólo las variables deben ser pasados ​​por referencia

function get_arr(){ 
    return array(1,2); 
} 
$el = array_shift(get_arr()); 

Así que cuando va a informar de la alerta de todos modos?

+1

¿Qué devuelve $ instance-> find (..)? –

+2

Aquí está la solución: http://stackoverflow.com/questions/9848295/strict-standards-only-variables-should-be-passed-by-reference-error – ajaristi

+0

Creo que los ejemplos (o lógica) podrían ser al revés en la pregunta, dado que el segundo ejemplo (función 'get_arr()') ** produce ** el aviso de estándares estrictos (probado PHP 5.2 y PHP 5.5). – MrWhite

Respuesta

7

$instance->find() devuelve la referencia a la variable.

Obtiene el informe cuando intenta utilizar esta referencia como argumento para funcionar, sin almacenarla primero en la variable.

Esto ayuda a prevenir fugas de memoria, y probablemente se convierta en error en las siguientes versiones de PHP.

Su segundo código lanzaría error si escribió como (nótese el & en firma de función):

function &get_arr(){ 
    return array(1,2); 
} 
$el = array_shift(get_arr()); 

Así que una solución rápida (y no tan bonito) sería:

$el = array_shift($tmp = $instance->find(..)); 

Básicamente, primero haces una asignación a la variable temporal y envías la variable como un argumento.

+1

Lo he probado anteriormente, no funciona – user198729

+0

Debería funcionar ahora (lo comprobó). Para devolver la referencia, debe declararla en la firma del método, no en la declaración de devolución (mi error). – Sagi

+0

No, no puedo cambiar la firma. La variable intermedia de @ pygorex1 puede resolver esto, pero parece redundante, ¿no? – user198729

90

Considere el siguiente código:

error_reporting(E_STRICT); 
class test { 
    function test_arr(&$a) { 
     var_dump($a); 
    } 
    function get_arr() { 
     return array(1,2); 
    } 
} 

$t= new test; 
$t->test_arr($t->get_arr()); 

Esto generará el siguiente resultado:

Strict Standards: Only variables should be passed by reference in test.php on line 14 
array(2) { 
    [0]=> 
    int(1) 
    [1]=> 
    int(2) 
} 

La razón? El método test::get_arr() no es una variable y en modo estricto esto generará una advertencia. Este comportamiento es extremadamente no intuitivo ya que el método get_arr()devuelve un valor de matriz.

Para solucionar este error en modo estricto, ya sea cambiar la firma del método para que no se utilice una referencia:

function test_arr($a) { 
    var_dump($a); 
} 

Como no se puede cambiar la firma de array_shift también se puede utilizar una variable intermedia:

$inter= get_arr(); 
$el= array_shift($inter); 
+4

Parece que no hay forma de evitar el uso de '$ inter' .. – user198729

+7

@ user198729: Estaba buscando una explicación o una solución, y encontré que puede usar current() para el primer elemento. Alas end() no funciona para el último ya que "avanza el puntero interno al último elemento". current (array_reverse (somefunction())) funciona (sí, es tonto) – MSpreij

+2

Es muy tonto. –

3

El segundo fragmento tampoco funciona y es por eso. array_shift es una función modificadora que cambia su argumento, por lo tanto, espera que su parámetro sea una referencia y no puede hacer referencia a algo que no sea una variable. Consulte las explicaciones de Rasmus aquí: http://bugs.php.net/bug.php?id=48937

5

La causa del error es el uso de la función interna de estructura de datos de programación de PHP, array_shift() [php.net/end]. La función toma una matriz como parámetro. Aunque en el prototipo de "array_shift()" en El manual se indica un signo de &, no hay una documentación de advertencia en la definición ampliada de esa función, ni existe ninguna explicación aparente de que el parámetro se haya pasado por referencia. esto es entendido /. No entendí, sin embargo, así que fue difícil para mí detectar la causa del error.

código

Reproducir:

function get_arr() 
{ 
return array(1,2); 
} 
$array = get_arr(); 
$el = array_shift($array); 
3

este código:

$monthly_index = array_shift(unpack('H*', date('m/Y'))); 

Editar para:

$date_time = date('m/Y'); 
$unpack = unpack('H*', $date_time); 
array_shift($unpack); 
-2

Pues bien, en los casos obvios, como que, se puede decir siempre PHP para suprimir los mensajes usando "@" al frente de la función.

$monthly_index = @array_shift(unpack('H*', date('m/Y')));

Puede que no sea una de las mejores prácticas de programación para suprimir todas las errores de esta manera, pero en ciertos casos (como éste) que es muy útil y es aceptable.

Como resultado, estoy seguro de que su amigo SysAdmin estará encantado con un "error.log" menos contaminado. ;)

+0

No sé quién rechazó esta respuesta, pero la solución presentada SI FUNCIONA y ES una técnica estándar de PHP. Realmente decepcionante ... La próxima vez podría no responder más una pregunta ... :( –

+3

Supongo que fue porque suprimir el mensaje de error no soluciona el problema con el código. ¿Qué vas a hacer cuando cambie este tipo de error? E_STRICT a E_ERROR en una futura versión de PHP y su código ahora no se ejecuta, y tampoco produce errores/salida? – Luke

+0

El uso de la supresión de errores nunca es la respuesta. La comunidad de PHP está intentando bastante para eliminar el uso de @ por nuevos codificadores, así que no aconseje a nadie que lo use. –

Cuestiones relacionadas