Cambios retroincompatibles

Cambios en el manejo de errores y excepciones

Muchos errores fatales y errores fatales recuperables han sido convertidos en excepciones en PHP 7. Estas excepciones de error heredan de la clase Error, la cual implementa en sí la interfaz Throwable, (la interfaz base que heredan todas las excepciones).

Esto significa que los manejadores de errores personalizados podrían no desencadenarse debido a que podrían lanzarse excepciones en su lugar (causando nuevos errores fatales para excepciones Error no capturadas).

Se puede encontrar una descripción más completa de cómo operan los errores en PHP 7 en la página de errores de PHP 7. Esta guía de migración simplemente enumerará los cambios que afectan a la retrocompatiblidad.

Ya no se garantiza que set_exception_handler() reciba objetos Exception

El código que implemente un manejador de excepciones registrado con set_exception_handler() empleando una declaración de tipo de Exception causará un error fatal cuando sea lance un objeto Error.

Si el manejador necesita funcionar tanto en PHP 5 como en PHP 7, se debería eliminar la declaración de tipo del manejador, mientras que el código que sea migrado para que funcione exclusivamente en PHP 7 puede simplemente reemplazar la declaración de tipo Exception con Throwable en su lugar.

<?php
// Código de la era de PHP 5 que no funcionará.
function handler(Exception $e) { ... }
set_exception_handler('handler');

// Compatible con PHP 5 y 7.
function handler($e) { ... }

// Solo PHP 7.
function handler(Throwable $e) { ... }
?>

Los constructores internos siempre lanzan excepciones en caso de fallo

Previamente, algunas clases internas devolvían null o un objeto inutilizable cuando el constructor fallaba. Ahora, todas las clases internas lanzan una Exception en tal caso, de la misma forma que las clases de usuario ya deben de hacerlo.

Los errores de análisis lanzan un objeto ParseError

Los errores de análisis ahora lanzan un objeto ParseError. El manejo de errores para eval() ahora debería incluir un bloque catch que permita manejar dicho error.

Cambios en la severidad de avisos E_STRICT

Todos los avisos de E_STRICT han sido reclasificados a otros niveles. Se mantiene la consntante E_STRICT, por lo que llamadas como error_reporting(E_ALL|E_STRICT) no ocasionarán ningún error.

Cambios en la severidad de avisos de E_STRICT
Situación Nuevo nivel/comportamiento
Indexación mediante un recurso E_NOTICE
Métodos estáticos abstractos Aviso eliminado, no genera un error
'Redefinición' de un constructor Aviso eliminado, no genera un error
Discordancia de la signatura durante la herencia E_WARNING
Misma propiedad (compatible) en dos rasgos empleados Aviso eliminado, no genera un error
Acceso a una propiedad estática de forma no estática E_NOTICE
Solamente las variables deberían ser asignadas por referencia E_NOTICE
Solamente las variables deberían ser pasadas por referencia E_NOTICE
Llamada a métodos no estáticos de forma estática E_DEPRECATED

Cambios en el manejo de variables

PHP 7 ahora emplea un árbol sintáctico abstracto al analizar ficheros. Esto ha permitido muchas mejoras en el lenguaje que antes eran imposibles debido a las limitaciones del analizador empleado en versiones previas de PHP, aunque ha resultado en la eliminación de unos pocos casos especiales por razones de consistencia, dando así lugar a roturas de retrocompatibilidad. Dichos casos están detallados a continuación.

Cambios en el manejo de variables, propiedades y métodos indirectos

El acceso indirecto a variables, propiedades y métodos ahora se evalúa estrictamente de izquierda a derecha, en contraste a la mezcla anterior de casos especiales. La tabla de abajo muestra los cambios en el orden de evaluación.

Antigua y nueva evaluación de expresiones indirectas
Expresión Interpretación de PHP 5 Interpretación de PHP 7
$$foo['bar']['baz'] ${$foo['bar']['baz']} ($$foo)['bar']['baz']
$foo->$bar['baz'] $foo->{$bar['baz']} ($foo->$bar)['baz']
$foo->$bar['baz']() $foo->{$bar['baz']}() ($foo->$bar)['baz']()
Foo::$bar['baz']() Foo::{$bar['baz']}() (Foo::$bar)['baz']()

El código que emplee el orden antiguo de evaluación de derecha a izquierda debe ser rescrito para utilizar explícitamente el orden de evaluación con llaves (véase la columna de en medio de arriba). Esto hará al código compatible con PHP 7.x y retrocompatible con PHP 5.x.

Cambios al manejo de list()

list() ya no asigna variables en orden inverso

list() ahora asigna valores a variables en el orden en el que estas se definen, en vez de en orden inverso. En general, esto solamente afecta al caso donde list() se emplea junto con el operador de array [], como se muestra a continuación:

<?php
list($a[], $a[], $a[]) = [123];
var_dump($a);
?>

Salida del ejemplo anterior en PHP 5:

array(3) {
  [0]=>
  int(3)
  [1]=>
  int(2)
  [2]=>
  int(1)
}

Salida del ejemplo anterior en PHP 7:

array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
}

En general, se recomienda no depender del orden en el que ocurren las asignaciones de list(), ya que este es un detalle de implementación que podría cambiar en el futuro.

Se han eliminado las asignaciones vacías de list()

Las construcciones de list() ya no pueden estar vacías. Lo siguiente ya no es válido:

<?php
list() = $a;
list(,,) = 
$a;
list(
$x, list(), $y) = $a;
?>
list() no puede desempaquetar strings

list() ya no puede desempaquetar variables de tipo string. Debería usarse str_split() en su lugar.

Cambio en el ordenamiento de arrays cuando los elementos se crean automáticamente durante las asignaciones por referencia

El orden de los elementos de un array ha cambiado cuando dichos elementos han sido creados automáticamente haciendo referencia a ellos en una asignación por referencia. Por ejemplo:

<?php
$array 
= [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
?>

Salida del ejemplo anterior en PHP 5:

array(2) {
  ["b"]=>
  &int(1)
  ["a"]=>
  &int(1)
}

Salida del ejemplo anterior en PHP 7:

array(2) {
  ["a"]=>
  &int(1)
  ["b"]=>
  &int(1)
}

global solamente acepta variables simples

Ya no se pueden utilizar variables variables con la palabra reservada global. Se puede emplear la sintaxis de llaves para emular el comportamiento anterior si fuera necesario:

<?php
function f() {
    
// Válido solamente en PHP 5.
    
global $$foo->bar;

    
// Válido en PHP 5 y 7.
    
global ${$foo->bar};
}
?>

Como principio general, se desaconseja el uso de global con algo que no sea una simple variable.

Los paréntesis alrededor de argumentos de una función ya no afectan al comportamiento

En PHP 5, el uso de paréntesis redundantes alrededor de un argumento de una función podía silenciar advertencias del estándar estricto cuando el argumento de dicha función era pasado por referencia. Estas advertencias ahora se emiten siempre.

<?php
function obtenerArray() {
    return [
123];
}

function 
arrayAlCuadrado(array &$a) {
    foreach (
$a as &$v) {
        
$v **= 2;
    }
}

// Genera una advertencia en PHP 7.
arrayAlCuadrado((obtenerArray()));
?>

El resultado del ejemplo sería:

Notice: Only variables should be passed by reference in /tmp/test.php on line 13

Cambios en foreach

Se han realizado cambios menores en el comportamiento de la estructura de control foreach, principalmente alrededor del manejo del puntero de arrays interno y la modificación del array en su recorrido.

foreach ya no cambia el puntero de arrays interno

Antes de PHP 7, el puntero de arrays interno era modificado mientras el array se recorría con foreach. Este ya no es el caso, como se muestra en el siguiente ejemplo:

<?php
$array 
= [012];
foreach (
$array as &$val) {
    
var_dump(current($array));
}
?>

Salida del ejemplo anterior en PHP 5:

int(1)
int(2)
bool(false)

Salida del ejemplo anterior en PHP 7:

int(0)
int(0)
int(0)

La iteración de foreach por valor opera sobre una copia del array

Al utilizar el modo predeterminado de iteración por valor, foreach ahora opera sobre una copia del array a recorrer en lugar del array en sí. Esto significa que los cambios realizados a un array durante una iteración no afectarán a los valores que se recorren.

Se ha mejorado el comportamiento de la iteración de foreach por referencia

Cuando se itera por referencia, foreach ahora realizará un trabajo mejor realizando un seguimiento de los cambios hechos en el array durante la iteración. Por ejemplo, al añadir valores a un array mientras se recorre dará como resultado también el recorrido de los valores añadidos:

<?php
$array 
= [0];
foreach (
$array as &$val) {
    
var_dump($val);
    
$array[1] = 1;
}
?>

Salida del ejemplo anterior en PHP 5:

int(0)

Salida del ejemplo anterior en PHP 7:

int(0)
int(1)

Iteración de objetos no Traversables

Recorrer un objeto no Traversable ahora tendrá el mismo comportamiento que recorrer arrays por referencia. Esto resulta en que la mejora del comportamiento al modificar un array durante la iteración se aplique también cuando se añaden propiedades a o se eleminan de un objeto.

Cambios en el manejo del tipo integer

Literales de octal inválidos

Previamente, los literales de octal que contenían números inválidos eran truncados silenciosamente (0128 era tomado como 012). Ahora, un literal de octal inválido causará un error de análisis.

Desplazamientos negativos de bits

Los desplazamientos de bit mediante números negativos ahora lanzan un ArithmeticError:

<?php
var_dump
(>> -1);
?>

Salida del ejemplo anterior en PHP 5:

int(0)

Salida del ejemplo anterior en PHP 7:

Fatal error: Uncaught ArithmeticError: Bit shift by negative number in /tmp/test.php:2
Stack trace:
#0 {main}
  thrown in /tmp/test.php on line 2

Desplazamientos de bits fuera de rango

Los desplazamientos de bits (en cualquier dirección) fuera del ancho de bit de un integer siempre resultarán en 0. Anteriormente, el comportamiento de dichos desplazamientos dependía de la arquitectura.

Cambios en la División por Cero

Anteriormente, cuando se empleaba 0 como divisor de los operadores de división (/) o módulo (%), se emitía un error de tipo E_WARNING y se devolvía false. Ahora, el operador de división devuelve un valor de tipo float así como +INF, -INF, o NAN tal como se especifica en el IEEE 754. El error E_WARNING del operador de módulo ha sido eliminado, lanzando ahora una excepción DivisionByZeroError.

<?php
var_dump
(3/0);
var_dump(0/0);
var_dump(0%0);
?>

Salida del ejemplo anterior en PHP 5:

Warning: Division by zero in %s on line %d
bool(false)

Warning: Division by zero in %s on line %d
bool(false)

Warning: Division by zero in %s on line %d
bool(false)

Salida del ejemplo anterior en PHP 7:

Warning: Division by zero in %s on line %d
float(INF)

Warning: Division by zero in %s on line %d
float(NAN)

PHP Fatal error:  Uncaught DivisionByZeroError: Modulo by zero in %s line %d

Cambios en el manejo del tipo string

Un string hexadecimal ya no se considera numérico

Los string que contienen números hexadecimales ya no se consideran numéricos. Por ejemplo:

<?php
var_dump
("0x123" == "291");
var_dump(is_numeric("0x123"));
var_dump("0xe" "0x1");
var_dump(substr("foo""0x1"));
?>

Salida del ejemplo anterior en PHP 5:

bool(true)
bool(true)
int(15)
string(2) "oo"

Salida del ejemplo anterior en PHP 7:

bool(false)
bool(false)
int(0)

Notice: A non well formed numeric value encountered in /tmp/test.php on line 5
string(3) "foo"

Se puede emplear filter_var() para comprobar si un string contiene un numero hexadecimal, y también para convertir un string de dicho tipo en un integer:

<?php
$str 
"0xffff";
$int filter_var($strFILTER_VALIDATE_INTFILTER_FLAG_ALLOW_HEX);
if (
false === $int) {
    throw new 
Exception("¡Número entero inválido!");
}
var_dump($int); // int(65535)
?>

\u{ puede ocasionar errores

Debido a la incorporación de la nueva sintaxis de escape de puntos de código de Unicode, los string que contienen un literal \u{ seguido de una secuencia inválida causarán un error fatal. Para evitarlo, se debería escapar la barra inicial.

Funciones eliminadas

call_user_method() y call_user_method_array()

Estas funciones estaban obsoletas en PHP 4.1.0 en favor de call_user_func() y call_user_func_array(). Se podría también considerar el uso de funciones variables y/o el operador ....

Todas las funciones ereg*

Se han eliminado todas las funciones de ereg. Se recomienda PCRE como alternativa.

Alias de mcrypt

Se ha eliminado la función obsoleta mcrypt_generic_end() en favor de mcrypt_generic_deinit().

También se han eliminado las funciones obsoletas mcrypt_ecb(), mcrypt_cbc(), mcrypt_cfb() y mcrypt_ofb() en favor del uso de mcrypt_decrypt() con la constante MCRYPT_MODE_* apropiada.

Todas las funciones de ext/mysql

Se han eliminado todas las funciones de ext/mysql. Para más detalles sobre elegir una API de MySQL diferente, Véase Elegir una API de MySQL.

Todas las funciones ext/mssql

Se han eliminado todas las funciones de ext/mssql.

Alias de intl

Se han eliminado los alias obsoletos datefmt_set_timezone_id() y IntlDateFormatter::setTimeZoneID() en favor de datefmt_set_timezone() y IntlDateFormatter::setTimeZone(), respectivamente.

set_magic_quotes_runtime()

Se ha eliminado set_magic_quotes_runtime(), junto con su alias magic_quotes_runtime(). Estaban obsoletos en PHP 5.3.0, y de hecho se quedaron sin funcionalidad con la eliminación de las comillas mágicas en PHP 5.4.0.

set_socket_blocking()

Se ha eliminado el alias obsoleto set_socket_blocking() en favor de stream_set_blocking().

dl() en PHP-FPM

dl() ya no se puede utilizar en PHP-FPM. Permanece funcional en CLI y en SAPI embebidas.

Funciones de Type1 de GD

Se ha eliminado el soporte para fuentes Type1 de PostScript de la extensión GD, resultado en la eliminación de las siguientes funciones:

  • imagepsbbox()
  • imagepsencodefont()
  • imagepsextendfont()
  • imagepsfreefont()
  • imagepsloadfont()
  • imagepsslantfont()
  • imagepstext()

Se recomienda utilizar fuentes TrueType y sus asociadas en su lugar.

Directivas INI eliminadas

Características eliminadas

Las siguientes directivas INI han sido eliminadas, así como sus características asociadas:

xsl.security_prefs

Ha sido eliminada la directiva xsl.security_prefs. En su lugar, debería llamarse al método XsltProcessor::setSecurityPrefs() para controlar las preferencias de seguridad en función de cada procesador.

Otros cambios retroincompatibles

No se pueden asignar nuevos objetos por referencia

El resultado de la sentencia new ya no se puede asignar a una variable por referencia:

<?php
class {}
$c =& new C;
?>

Salida del ejemplo anterior en PHP 5:

Deprecated: Assigning the return value of new by reference is deprecated in /tmp/test.php on line 3

Salida del ejemplo anterior en PHP 7:

Parse error: syntax error, unexpected 'new' (T_NEW) in /tmp/test.php on line 3

Nombres de clase, interfaz y rasgo inválidos

Los siguientes nombres no se pueden emplear para nombrar a clases, interfaces o rasgos:

  • bool
  • int
  • float
  • string
  • null
  • true
  • false

Tampoco deberían utilizarse los siguientes nombres. Aunque no generan un error en PHP 7.0, están reservados para un uso futuro, por lo que deberían considerarse obsoletos.

  • resource
  • object
  • mixed
  • numeric

Eliminación de las etiquetas ASP y de script de PHP

Se ha eliminado el soporte para usar etiquetas ASP y de script para delimitar código de PHP. Las etiquetas afectadas son:

Etiquetas ASP y de script eliminadas
Etiqueta de apertura Etiqueta de cierre
<% %>
<%= %>
<script language="php"> </script>

Eliminación de llamadas desde contextos incompatibles

Ya obsoletas en PHP 5.6, las llamadas estáticas realizadas a un método no estático con un contexto incompatible resultarán ahora en la tenencia del método llamado de una variable $this indefinida y en la emisión de una advertencia de obsolescencia.

<?php
class {
    public function 
prueba() { var_dump($this); }
}

// Nota: NO extiende a A
class {
    public function 
llamadaAMétodoNoEstáticoDeA() { A::prueba(); }
}

(new 
B)->llamadaAMétodoNoEstáticoDeA();
?>

Salida del ejemplo anterior en PHP 5.6:

Deprecated: Non-static method A::prueba() should not be called statically, assuming $this from incompatible context in /tmp/test.php on line 8
object(B)#1 (0) {
}

Salida del ejemplo anterior en PHP 7:

Deprecated: Non-static method A::prueba() should not be called statically in /tmp/test.php on line 8

Notice: Undefined variable: this in /tmp/test.php on line 3
NULL

yield ahora es un operador asociativo derecho

El constructor yield ya no requiere paréntesis, ya que ha pasado a ser un operador asociativo derecho con precedencia entre print y =>. Esto puede resultar en un cambio de comportamiento:

<?php
echo yield -1;
// Anteriormente era interpretado como
echo (yield) - 1;
// Y ahora es intrepretado como
echo yield (-1);

yield 
$foo or die;
// Anteriormente era interpretado como
yield ($foo or die);
// Y ahora es intrepretado como
(yield $foo) or die;
?>

Los paréntesis se pueden emplear para desambiguar estos casos.

Las funciones no pueden tener varios parámetros con el mismo nombre

Ya no es posible definir dos o más parámetros de función con el mismo nombre. Por ejemplo, el siguiente método generará un error E_COMPILE_ERROR:

<?php
function foo($a$b$sin_usar$sin_usar) {
    
//
}
?>

Las funciones que inspeccionan argumentos informan del valor del parámetro actual

func_get_arg(), func_get_args(), debug_backtrace() y las excepciones de información de rastreo ya no informarán del valor original que fue pasado a un paramétro, en su lugar proporcionarán el valor actual (el cual podría haber sido modificado).

<?php
function foo($x) {
    
$x++;
    
var_dump(func_get_arg(0));
}
foo(1);?>

Salida del ejemplo anterior en PHP 5:

1

Salida del ejemplo anterior en PHP 7:

2

Las sentencias switch no pueden tener varios bloques default

Ya no es posible definir dos o más bloques default en una sentencia switch. Por ejemplo, la siguiente senetencia switch generará un error E_COMPILE_ERROR:

<?php
switch (1) {
    default:
    break;
    default:
    break;
}
?>

Eliminación de $HTTP_RAW_POST_DATA

$HTTP_RAW_POST_DATA ya no está disponible. Debería usarse el flujo php://input en su lugar.

Eliminación de los comentarios # en ficheros INI

Se ha eliminado el soporte para los comentarios prefijados con # en los ficheros INI. Se debe emplear en su lugar ; (punto y coma). Este cambio se aplica a php.ini, así como a ficheros manejados por parse_ini_file() y parse_ini_string().

JSON extension replaced with JSOND

Se ha reemplazado la extensión JSON por JSOND ocasionando tres roturas de RC (retocompatibilidad). La primera, un número no puede finalizar con un punto decimal (esto es, 34. debe cambiarse para que sea o 34.0 o 34). La segunda, al utilizar notación científica, el exponente e no debe seguir inmediatamente a un punto decimal (esto es, 3.e3 se debe cambiar para que sea o 3.0e3 o 3e3). Finalmente, una cadena vacía ya no se considera un JSON válido.

Fallo de funciones internas en un desbordamiento

Anteriormente, las funciones internas truncaban de forma silenciosa números producidos desde coacciones de tipo float a integer cuando el float era demasiado grande de representar como un integer. Ahora, se emitirá un E_WARNING y se devolverá null.

Reparaciones en los valores de devolución de gestores de sesión personalizados

Cualquier función declarada implementada por gestores de sesión personalizados que devuelvan o false o -1 serán errores fatales. Si desde estas funciones se devuelve cualquier valor distinto de un booleano, -1, o 0, fallarán y se emitirá un E_WARNING.

Sort order of equal elements

El algoritmo de ordenación interno ha sido mejorado, lo cual puede resultar en un orden diferente de elementos, que se comparan como iguales, que antes.

Nota:

No dependa del orden de los elementos que se comparan como iguales; podría cambiar en cualquier momento.

add a note add a note

User Contributed Notes 11 notes

up
180
me at fquff dot io
8 years ago
[Editor's note: fixed limit on user request]

As a mathematician, 3/0 == +INF IS JUST WRONG. You can't just assume 3/0 == lim_{x->0+} 3/x, which is +INF indeed, because division IS NOT A CONTINUOUS FUNCTION in x == 0.

Also, 3/0 == +INF ("positive" infinity) while -3/0 == -INF ("negative" infinity) requires the assumption that 0 is a positive number, which is just as illogical as it looks like.

The fact that a warning is emitted is good, but it should definitely equals to NaN. ±INF is just illogical (and arithmetically wrong).

Except for this "detail", looks an amazing update, can't wait to test it even further!

Cheers,
P.
up
126
tuxedobob
8 years ago
As a programmer, I don't care whether 3/0 is INF or NaN. Both answers are (probably) equally useless, and tell me that something somewhere else is screwed up.
up
101
mossy2100
8 years ago
Although $x/0 is technically not infinity in a purely mathematical sense, when you understand why the IEEE float includes a value for infinity, and returns infinity in this case, it makes sense that PHP would agree with this.

The reason is that programmers don't usually divide by 0 on purpose. A value of 0 as a divisor usually occurs due to underflow, i.e. a value which is too small to be represented as a float. So, for example, if you have values like:
$x = 1;
$y = 1e-15 * 1e-15;
$z = $x/$y;
Because $y will have underflowed to 0, the division operation will throw the division by zero warning, and $z will be set to INF. In a better computer, however, $y would not have the value 0 (it would be 1e-30) and $z would not have the value INF (it would be 1e30).

In other words, 0 is not only representative of an actual 0, but also a very small number which float cannot represent correctly (underflow), and INF does not only represent infinity, but also a very big number which float cannot represent correctly (overflow). We do the best we can within the limitations of floating point values, which are really just good approximations of the actual numbers being represented.

What does bother me is that division by zero is handled in two different ways depending on the operator. I would have preferred the new DivisionByZeroError exception to be thrown in all cases, for consistency and to enforce good programming practices.
up
6
maba at mb-systemhaus dot net
7 years ago
NOTE:
the new variable handling in PHP 7 also has side effects on the COM .NET extension. Numeric variants (in the Windows application space) now must be quoted when passed over from PHP. This is the case when the receiving application expects a variable of type variant.

Here is an example:

<?php
  $word
= new COM('Word.Application');

 
// now load a document, ...

  // the following works in PHP 5 but will throw an exception in PHP 7
 
$word->ActiveDocument->PrintOut(false, false, 0, $outfile);

 
// the following works in PHP 7 as well, please note the quotes around the '0'
 
$word->ActiveDocument->PrintOut(false, false, '0', $outfile);
?>
up
12
tkondrashov at gmail dot com
5 years ago
split() was also removed in 7.0, so be sure to check your old code for it as well as the functions listed in this doc
up
11
Frank
8 years ago
[Editor's Note: that change is listed in the "Changed functions" section.]

The substr function has also been changed in a backward incompatible way.

<?php
substr
("test",4);  # false in PHP 5,  "" in PHP 7
?>

In fact, this is the only thing we had to change in a number of places for our code base to run on PHP 7. It's definitely an improvement though, as the old behavior tended to cause bugs in border cases.
up
1
ilya dot chase at yandex dot ru
5 years ago
Take note that in preg_replace() function, flag '\e' was deleted in PHP 7.0.0. This function will return null always with this flag. Doc: https://www.php.net/manual/ru/function.preg-replace.php
up
0
Anonymous
3 years ago
Question to "Functions cannot have multiple parameters with the same name":

function foo($a, $b, $unused, $unused)

What's the regular expression to match two params of the same name?
up
0
viktor dot csiky at nospam dot nospam dot eu
7 years ago
It is stated:

"foreach by-value operates on a copy of the array

When used in the default by-value mode, foreach will now operate on a copy of the array being iterated rather than the array itself. This means that changes to the array made during iteration will not affect the values that are iterated."

Please note that this is not exactly true. New foreach operates on a copy of the array, by-value or by-reference. It seems that in the latter case, the array copy is simply moved over (to) the original array before it is presumably destroyed.

As a consequence of this, you may not "dereference" an array containing values - e.g. for use with ReflectionMethod::invokeArgs() or the good ole' call_user_func().
Consider the snippet below:

<?php
function deref(Array $inputArray)
{
       
$retVal = [];
       
        foreach (
$inputArray as &$inputValue)
        {
           
$retVal[] = $inputValue;
        }

        return
$retVal;
}
?>

As of PHP 7.0, this *will no longer work*. You will get the usual suspect:

PHP Warning:  Parameter n to whatever() expected to be a reference, value given in baz.php on line x

You need to convert it to explicitly reference the original array:
<?php
function deref(Array $inputArray)
{
       
$retVal = [];
       
        foreach (
$inputArray as $inputKey => $inputValue)
        {
           
$retVal[$inputKey] = &$inputArray[$inputKey];
        }

        return
$retVal;
}
?>

PLEASE NOTE that this might have the unforeseen consequence of your code not working anymore in php versions less than 5.3 (that is, 5.2 and below).
up
-11
Ray.Paseur sometimes uses Gmail
7 years ago
In the section captioned "Changes to the handling of indirect variables, properties, and methods" there are parentheses used in the table directly beneath "PHP 7 interpretation." 

The parentheses are intended to show the evaluation order, but they are not part of the syntax, and should not be used in the variable definition or reference.  This juxtaposition confused one of my colleagues; hopefully this note will save someone else some time.

Examples of the correct curly-brace syntax is further down the page, in the section captioned "global only accepts simple variables."
To Top