variable una referencia por paso pasar parametros otra funcion array php error-handling variables reference

php - una - Solo se pueden pasar las variables por referencia



paso por referencia (7)

Tuve la brillante idea de usar un controlador de errores personalizado que me llevó por un agujero de conejo.

El siguiente código proporciona (con y sin controlador de errores personalizado): Error grave: solo se pueden pasar las variables por referencia

function foo(){ $b=array_pop(array("a","b","c")); return $b; } print_r(foo());

El siguiente código proporciona ( solo con un controlador de errores personalizado ): (2048) Solo las variables deben pasarse por referencia

function foo(){ $a=explode( ''/'' , ''a/b/c''); $c=array_pop(array_slice($a,-2,1)); return $c; } print_r(foo());

El segundo me preocupa porque tengo un montón de código "compacto". Entonces, o me deshago de la brillante idea de usar un controlador de errores personalizado (para mejorar mi módulo de registro) o expandir todo mi código.

¿Alguien con mejores ideas? Además, WTF?

ACTUALIZACIÓN :

Gracias a las respuestas, he aprendido algo sobre cómo php hace el manejo de errores. La confusión de E_ALL que no incluye E_STRICT (php 5) no es buena.

Además de todo esto, la creación de su propio controlador de errores personalizado habilita E_STRICT de forma predeterminada y ahí es donde comienzan los problemas.

La moraleja de la historia es usar su propio controlador de errores para detectarlos TODOS y usar las constantes de error (E_STRICT, E_USER_WARNING, E_USER_ERROR, etc.) para realizar el filtrado.

En cuanto al ''problema de corrupción de memoria'' con referencias variables y ciertas funciones, ¿qué puedo decir? Doblemente uncool. Voy a (lo que no significa que debas) ignorar E_STRICT en mi controlador de errores y la vida continúa.


Creo que ahora (desde php 5) debería ser:

function &foo(){ //NOTICE THE & $b=array_pop(array("a","b","c")); return $b; } print_r(foo());

y

function &foo(){ //NOTICE THE & $a=explode( ''/'' , ''a/b/c''); $c=array_pop(array_slice($a, $b = -2, $c = 1)); //NOW NO DIRECT VALUES ARE PASSED IT MUST BE VARIABLES return $c; } print_r(foo());

pero solo soy un principiante :)


Es un problema de corrupción de memoria (según el equipo de desarrollo de PHP). Solo tira una tarea:

function foo(){ $b = array_pop($arr = array("a","b","c")); return $b; } print_r(foo());

:

function foo(){ $a = explode( ''/'' , ''a/b/c''); $c = array_pop($arr = array_slice($a,-2,1)); return $c; } print_r(foo());

El segundo produce un E_STRICT. Puede manejar eso de manera diferente en su controlador de errores si lo desea (si no desea cambiar esas funciones).


Esto es lo que obtengo cuando intento su segundo fragmento de código php en php-cli después de configurar error_reporting en E_ALL | E_STRICT

gparis@techosaure:~/workspace/universcine.com$ php -a Interactive shell php > function foo(){ php { $a=explode( ''/'' , ''a/b/c''); php { $c=array_pop(array_slice($a,-2,1)); php { return $c; php { } php > print_r(foo()); PHP Strict standards: Only variables should be passed by reference in php shell code on line 3 PHP Stack trace: PHP 1. {main}() php shell code:0 PHP 2. foo() php shell code:1

Como puede ver, aquí solo se aplican normas estrictas. Además, puede dejar que su controlador de errores personalizado los ignore (según el valor que obtenga: 2048, por ejemplo, aquí).

A partir de php 5.3, E_ALL no incluye E_STRICT, mira esto:

php > foreach(array("E_ALL", "E_DEPRECATED", "E_STRICT", "E_NOTICE", "E_PARSE", "E_WARNING") as $const) echo $const . " :/t" . constant($const) ."/t". decbin(constant($const)). "/n"; E_ALL : 30719 111011111111111 E_DEPRECATED : 8192 10000000000000 E_STRICT : 2048 100000000000 E_NOTICE : 8 1000 E_PARSE : 4 100 E_WARNING : 2 10

A partir de PHP 5.4, E_ALL incluye E_STRICT :

E_ALL : 32767 111111111111111 E_DEPRECATED : 8192 10000000000000 E_STRICT : 2048 100000000000 E_NOTICE : 8 1000 E_PARSE : 4 100 E_WARNING : 2 10


Prueba esto:

function foo(){ $a = array("a","b","c"); $b = array_pop($a); return $b; }


array_pop () intenta cambiar el valor que se pasa como parámetro. Ahora en su segundo ejemplo, este es el valor de retorno de array_slice (). En términos de motor, este es un "valor temporal" y dicho valor no puede ser pasado por referencias. Lo que necesitas es una variable temporal:

function foo(){ $a=explode( ''/'' , ''a/b/c''); $b=array_slice($a,-2,1); $c=array_pop($b); return $c; } print_r(foo());

Luego se puede pasar una referencia a $ b a array_pop (). Vea http://php.net/references para más detalles sobre referencias.



array_pop() cambia el valor que se le pasa, que es de donde viene el error. Una función no puede ser cambiada. En otras palabras, primero debe asignar la matriz a una variable (ref: manual ) y luego ejecutar array_pop() .

El código que necesitas es este:

function foo(){ $a = array("a","b","c"); $b = array_pop($a); return $b; }

Edit: Ambas funciones que mencionaste tienen el mismo problema. Asigne la matriz a una variable y pase la variable a array_pop() .