¿Hay alguna forma de solucionar este problema fácilmente o realmente necesito volver a escribir todo el código heredado?
Error fatal de PHP: el paso por referencia de tiempo de llamada se eliminó en … en la línea 30
Esto sucede en todas partes, ya que las variables se pasan a funciones como referencias en todo el código.
Debe 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 obsolescencia en la versión 5.3, diría que sería una buena idea reescribir el código.
De la documentación:
No hay un signo de referencia en una llamada de función, solo en definiciones de función. Las definiciones de función por sí solas son suficientes para pasar correctamente el argumento por referencia. A partir de PHP 5.3.0, recibirá una advertencia que dice que “call-time pass-by-reference” está obsoleto cuando usa &
en foo(&$a);
.
Por ejemplo, en lugar de usar:
// Wrong way!
myFunc(&$arg); # Deprecated pass-by-reference argument
function myFunc($arg) { }
Utilizar:
// Right way!
myFunc($var); # pass-by-value argument
function myFunc(&$arg) { }
Para cualquiera que, como yo, lea esto porque necesita actualizar un proyecto heredado gigante a 5.6: como señalan las respuestas aquí, no hay una solución rápida: realmente necesita encontrar cada aparición del problema manualmente y arreglarlo .
La forma más conveniente que encontré para encontrar todas las líneas problemáticas en un proyecto (aparte de usar un analizador de código estático completo, 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 PHP linter incorporado, y su función de búsqueda que permite buscar por Regex. (Por supuesto, puede usar cualquier editor IDE/Código para esto que realice búsquedas PHP Linting y Regex).
Usando esta expresión regular:
^(?!.*function).*(\&\$)
es posible buscar en todo el proyecto la ocurrencia de &$
solo en líneas que no son una definición de función.
Esto todavía arroja muchos falsos positivos, pero facilita el trabajo.
El navegador de resultados de búsqueda de VSCode hace que caminar y encontrar las líneas ofensivas sea muy fácil: simplemente haga clic en cada resultado y busque aquellos que el linter subraya en rojo. Los que necesitas arreglar.
PHP y las referencias son algo poco intuitivas. Si se usan correctamente, las referencias en los lugares correctos pueden proporcionar grandes mejoras de rendimiento o evitar soluciones alternativas muy desagradables y código inusual.
Lo siguiente producirá un error:
function f(&$v){$v = true;}
f(&$v);
function f($v){$v = true;}
f(&$v);
Ninguno de estos debe fallar, ya que podrían seguir las reglas a continuación, pero sin duda se eliminaron o deshabilitaron para evitar mucha confusión heredada.
Si funcionaron, ambos implican una conversión redundante a referencia y el segundo también implica una conversión redundante a una variable contenida en el ámbito.
El segundo solía ser posible al permitir que se pasara una referencia a un código que no estaba destinado a trabajar con referencias. Esto es extremadamente feo para la mantenibilidad.
Esto no hará nada:
function f($v){$v = true;}
$r = &$v;
f($r);
Más específicamente, vuelve a convertir la referencia en una variable normal ya que no ha solicitado una referencia.
Esto funcionará:
function f(&$v){$v = true;}
f($v);
Esto ve que está pasando una no referencia pero quiere una referencia, así que la convierte en una referencia.
Lo que esto significa es que no puede pasar una referencia a una función en la que no se solicita explícitamente una referencia, lo que la convierte en una de las pocas áreas en las que PHP es estricto en el paso de tipos o, en este caso, más de un metatipo.
Si necesita un comportamiento más dinámico, esto funcionará:
function f(&$v){$v = true;}
$v = array(false,false,false);
$r = &$v[1];
f($r);
Aquí ve que desea una referencia y ya tiene una referencia, así que déjelo en paz. También puede encadenar la referencia, pero lo dudo.
Relacionado: advertencia de PHP: el paso por referencia en el tiempo de llamada ha quedado obsoleto
– Palec
26 dic 2014 a las 14:30