2012-01-23 6 views
198

¿Hay alguna manera de solucionar fácilmente este problema o realmente necesito volver a escribir todo el código heredado?PHP 5.4 Tiempo de pasada por referencia de la referencia - ¿Solución fácil disponible?

PHP Fatal error: Call-time pass-by-reference has been removed in ... on line 30

Esto sucede en todas partes, las variables se pasan a funciones como referencias en todo el código.

+0

Relacionado: [Advertencia de PHP: el tiempo de pasada de referencia de la llamada ha quedado obsoleto] (http://stackoverflow.com/q/4665782/2157640) – Palec

Respuesta

314

Debería indicar la llamada por referencia en la definición de la función, no la llamada real. Dado que PHP comenzó a mostrar los errores de desaprobación en la versión 5.3, diría que sería una buena idea reescribir el código.

From the documentation:

There is no reference sign on a function call - only on function definitions. Function definitions alone are enough to correctly pass the argument by reference. As of PHP 5.3.0, you will get a warning saying that "call-time pass-by-reference" is deprecated when you use & in foo(&$a); .

Por ejemplo, en lugar de utilizar:

// Wrong way! 
myFunc(&$arg);    # Deprecated pass-by-reference argument 
function myFunc($arg) { } 

Uso:

// Right way! 
myFunc($var);    # pass-by-value argument 
function myFunc(&$arg) { } 
+8

Lástima :(- Estoy portando de 5.2 a 5.4 y esto es realmente molesto ... – bardiir

+9

La depreciación es desde PHP 5.0.0, en el pasado el error de nivel 'E_COMPILE_WARNING', para referencia: http://www.php.net/manual/en/ini.core.php# ini.allow-call-time-pass-reference – hakre

+5

Tuve este error pero necesitaba eliminar el & insted de agregar a la variable. – Diana

5

PHP y las referencias son algo poco intuitivo. Si se usan adecuadamente, las referencias en los lugares correctos pueden proporcionar grandes mejoras de rendimiento o evitar soluciones poco fiables y códigos inusuales.

A continuación se producirá un error:

function f(&$v){$v = true;} 
f(&$v); 

function f($v){$v = true;} 
f(&$v); 

Ninguno de ellos tiene que fallar, ya que podrían seguir las reglas de abajo, pero tienen sin duda ha eliminado o desactivado para evitar mucha confusión legado.

Si funcionaron, ambos implican una conversión redundante a referencia y el segundo también implica una conversión redundante a una variable contenida con ámbito.

El segundo solía ser posible permitiendo pasar una referencia al código que no estaba destinado a trabajar con referencias. Esto es extremadamente feo para el mantenimiento.

Esto no hará nada:

function f($v){$v = true;} 
$r = &$v; 
f($r); 

Más específicamente, se convierte la referencia de nuevo en una variable normal ya que no se ha solicitado una referencia.

Esto funcionará:

function f(&$v){$v = true;} 
f($v); 

Esto da cuenta de que está de paso un no-referencia, pero desea una referencia por lo convierte en una referencia.

Lo que esto significa es que no puede pasar una referencia a una función donde no se solicita explícitamente una de las pocas áreas donde PHP es estricto para pasar tipos o en este caso más de un meta tipo .

Si necesita un comportamiento más dinámico que esto funcionará:

function f(&$v){$v = true;} 
$v = array(false,false,false); 
$r = &$v[1]; 
f($r); 

Aquí se ve que usted desee una referencia y ya tiene una referencia para lo deja solo. También puede encadenar la referencia, pero lo dudo.

3

Para cualquiera que, como yo, lea esto porque necesita actualizar un proyecto legado gigante a 5.6: como las respuestas aquí señalan, no hay una solución rápida: realmente necesita encontrar cada ocurrencia del problema manualmente y arreglarlo

La forma más conveniente que encontré para encontrar todas las líneas problemáticas en un proyecto (excepto el uso de un analizador de código estático en toda regla, que es muy preciso pero no conozco ninguno que lo lleve a la posición correcta en el editor de inmediato) estaba usando Visual Studio Code, que tiene un buen lintero PHP integrado, y su función de búsqueda que permite buscar por Regex. (Por supuesto, puede utilizar cualquier editor/Código IDE para esto que hace PHP pelusa y las búsquedas de expresiones regulares.)

Utilizando esta expresión regular:

^(?!.*function).*(\&\$) 

es posible buscar en todo el proyecto para la ocurrencia de &$ solo en líneas que no son una definición de función.

Esto sigue generando muchos falsos positivos, pero facilita el trabajo.

El buscador de resultados de búsqueda de VSCode hace que caminar y encontrar las líneas ofensivas sea súper fácil: simplemente haga clic en cada resultado y observe los que el linter subraya en rojo. Aquellos que necesitas arreglar.

+1

¡Esto es lo que estaba buscando! – Sonny

+1

Regex más precisa que estoy usando para este propósito: '(? ] [a-zA-Z0-9 _] + (? Mojo

Cuestiones relacionadas