-
match es ahora una palabra reservada.
-
Los fallos de aserción ahora lanzan una excepción por defecto. Si se desea el comportamiento
anterior, se puede establecer assert.exception=0 en la configuración INI.
-
Los métodos con el mismo nombre que la clase ya no se interpretan como constructores. Se debe
usar el método __construct() en su lugar.
-
La posibilidad de llamar a métodos no estáticos de forma estática ha sido eliminada. Por lo
tanto, is_callable() fallará al verificar un método no estático con un nombre
de clase (se debe verificar con una instancia de objeto).
-
Las conversiones (real) y (unset) han sido eliminadas.
-
La directiva ini track_errors ha sido eliminada. Esto
significa que php_errormsg ya no está disponible. Se puede usar la función
error_get_last() en su lugar.
-
La posibilidad de definir constantes insensibles a mayúsculas y minúsculas ha sido eliminada. El
tercer argumento de define() ya no puede ser true.
-
La posibilidad de especificar un autocargador utilizando una función
__autoload() ha sido eliminada. Se debe usar
spl_autoload_register() en su lugar.
-
El argumento errcontext ya no se pasará a los manejadores de errores
personalizados establecidos con set_error_handler().
-
create_function() ha sido eliminada. Se pueden usar funciones anónimas en su
lugar.
-
each() ha sido eliminada. Se debe usar foreach o
ArrayIterator en su lugar.
-
La posibilidad de desvincular this de closures que fueron creadas a partir de
un método, utilizando Closure::fromCallable() o
ReflectionMethod::getClosure(), ha sido eliminada.
-
La posibilidad de desvincular this de closures propias que contienen usos de
this también ha sido eliminada.
-
La posibilidad de usar array_key_exists() con objetos ha sido eliminada. Se
puede usar isset() o property_exists() en su lugar.
-
El comportamiento de array_key_exists() en relación con el tipo del parámetro
key se ha hecho consistente con isset() y el acceso
normal a arrays. Todos los tipos de clave ahora usan las coerciones habituales y las claves de
tipo array/object lanzan un TypeError.
-
Cualquier array que tenga un número n como su primera clave numérica
usará n+1 para su siguiente clave implícita, incluso si
n es negativo.
-
El nivel predeterminado de error_reporting es ahora E_ALL. Anteriormente
excluía E_NOTICE y E_DEPRECATED.
-
display_startup_errors está ahora habilitado
por defecto.
-
Usar parent dentro de una clase que no tiene padre ahora resultará en un error fatal
en tiempo de compilación.
-
El operador @ ya no silenciará los errores fatales
(E_ERROR, E_CORE_ERROR,
E_COMPILE_ERROR, E_USER_ERROR,
E_RECOVERABLE_ERROR, E_PARSE). Los manejadores de
errores que esperan que error_reporting sea 0 cuando se usa
@, deben ajustarse para usar una verificación de máscara en su lugar:
<?php
// Reemplazar
function my_error_handler($err_no, $err_msg, $filename, $linenum) {
if (error_reporting() == 0) {
return; // Silenciado
}
// ...
}
// Por
function my_error_handler($err_no, $err_msg, $filename, $linenum) {
if (!(error_reporting() & $err_no)) {
return; // Silenciado
}
// ...
}
?>
Además, se debe tener cuidado de que los mensajes de error no se muestren en entornos de
producción, lo que puede resultar en fugas de información. Es necesario asegurarse de que
display_errors=Off se use junto con el registro de errores.
-
#[ ya no se interpreta como el inicio de un comentario, ya que esta sintaxis
ahora se usa para atributos.
-
Los errores de herencia debidos a firmas de métodos incompatibles (violaciones de LSP) ahora
siempre generarán un error fatal. Anteriormente se generaba una advertencia en algunos casos.
-
La precedencia del operador de concatenación ha cambiado en relación con los desplazamientos de
bits y la suma, así como la resta.
<?php
echo "Sum: " . $a + $b;
// anteriormente se interpretaba como:
echo ("Sum: " . $a) + $b;
// ahora se interpreta como:
echo "Sum:" . ($a + $b);
?>
-
Los argumentos con un valor predeterminado que se resuelve a null en tiempo de ejecución ya no
marcarán implícitamente el tipo del argumento como nullable. Se debe usar un tipo nullable
explícito o un valor predeterminado null explícito en su lugar.
<?php
// Reemplazar
function test(int $arg = CONST_RESOLVING_TO_NULL) {}
// Por
function test(?int $arg = CONST_RESOLVING_TO_NULL) {}
// O
function test(int $arg = null) {}
?>
-
Varias advertencias se han convertido en excepciones Error:
-
Intentar escribir en una propiedad de un no-objeto. Anteriormente esto creaba implícitamente
un objeto stdClass para null, false y cadenas vacías.
-
Intentar agregar un elemento a un array cuya clave PHP_INT_MAX ya está en uso.
-
Intentar usar un tipo no válido (array u objeto) como clave de array u offset de cadena.
- Intentar escribir en un índice de array de un valor escalar.
- Intentar desempaquetar un valor que no es array/Traversable.
-
Intentar acceder a constantes no calificadas que no están definidas. Anteriormente, el acceso
a constantes no calificadas resultaba en una advertencia y se interpretaban como cadenas.
Varios avisos se han convertido en advertencias:
- Intentar leer una variable no definida.
- Intentar leer una propiedad no definida.
- Intentar leer una clave de array no definida.
- Intentar leer una propiedad de un no-objeto.
- Intentar acceder a un índice de array de un no-array.
- Intentar convertir un array a cadena.
- Intentar usar un recurso como clave de array.
- Intentar usar null, un booleano o un flotante como offset de cadena.
- Intentar leer un offset de cadena fuera de los límites.
- Intentar asignar una cadena vacía a un offset de cadena.
-
Intentar asignar múltiples bytes a un offset de cadena ahora emitirá una advertencia.
-
Los caracteres inesperados en los archivos fuente (como bytes NUL fuera de las cadenas) ahora
resultarán en una excepción ParseError en lugar de una advertencia de
compilación.
-
Las excepciones no capturadas ahora pasan por un "cierre limpio", lo que significa que los
destructores se llamarán después de una excepción no capturada.
-
El error fatal en tiempo de compilación "Only variables can be passed by reference" se ha
pospuesto hasta el tiempo de ejecución y se ha convertido en una excepción
Error "Argument cannot be passed by reference".
-
Algunos avisos "Only variables should be passed by reference" se han convertido en la excepción
"Argument cannot be passed by reference".
-
El nombre generado para las clases anónimas ha cambiado. Ahora incluirá el nombre de la primera
clase padre o interfaz:
<?php
new class extends ParentClass {};
// -> ParentClass@anonymous
new class implements FirstInterface, SecondInterface {};
// -> FirstInterface@anonymous
new class {};
// -> class@anonymous
?>
El nombre mostrado arriba todavía va seguido de un byte NUL y un sufijo único.
-
Las referencias a métodos de trait no absolutas en las adaptaciones de alias de trait ahora deben
ser inequívocas:
<?php
class X {
use T1, T2 {
func as otherFunc;
}
function func() {}
}
?>
Si tanto T1::func() como T2::func() existen, este código era aceptado
silenciosamente antes, y se asumía que func se refería a T1::func. Ahora generará un
error fatal en su lugar, y se debe escribir explícitamente T1::func o
T2::func.
-
La firma de los métodos abstractos definidos en traits ahora se verifica contra el método de la
clase que los implementa:
<?php
trait MyTrait {
abstract private function neededByTrait(): string;
}
class MyClass {
use MyTrait;
// Error, debido a la incompatibilidad del tipo de retorno.
private function neededByTrait(): int { return 42; }
}
?>
-
Las funciones deshabilitadas ahora se tratan exactamente como funciones inexistentes. Llamar a
una función deshabilitada la reportará como desconocida, y redefinir una función deshabilitada
ahora es posible.
-
Los envoltorios de flujo data:// ya no son escribibles, lo que coincide con el
comportamiento documentado.
-
Los operadores aritméticos y a nivel de bits +, -,
*, /, **, %,
<<, >>, &,
|, ^, ~, ++,
-- ahora lanzarán consistentemente un TypeError cuando
uno de los operandos sea un array, resource u object no sobrecargado. La única excepción a
esto es la operación de fusión de arrays +, que sigue siendo soportada.
-
La conversión de flotante a cadena ahora siempre se comportará de manera independiente de la
configuración regional.
<?php
setlocale(LC_ALL, "de_DE");
$f = 3.14;
echo $f, "\n";
// Anteriormente: 3,14
// Ahora: 3.14
?>
Véase printf(), number_format() y
NumberFormatter() para formas de personalizar el formato de números.
-
El soporte para el acceso a offsets con llaves (obsoleto) ha sido eliminado.
<?php
// En lugar de:
$array{0};
$array{"key"};
// Escribir:
$array[0];
$array["key"];
?>
-
Aplicar el modificador final en un método privado ahora producirá una advertencia a menos que ese
método sea el constructor.
-
Si el constructor de un objeto llama a exit(), el destructor del objeto ya no
se llamará. Esto coincide con el comportamiento cuando el constructor lanza una excepción.
-
Los nombres con espacio de nombres ya no pueden contener espacios en blanco: Mientras que
Foo\Bar se reconocerá como un nombre con espacio de nombres,
Foo \ Bar no. Por el contrario, las palabras reservadas ahora están permitidas como
segmentos de espacio de nombres, lo que también puede cambiar la interpretación del código:
new\x ahora es lo mismo que constant('new\x'), no
new \x().
-
Los ternarios anidados ahora requieren paréntesis explícitos.
-
debug_backtrace() y Exception::getTrace() ya no
proporcionarán referencias a los argumentos. No será posible cambiar los argumentos de una
función a través del backtrace.
-
El manejo de cadenas numéricas ha sido modificado para ser más intuitivo y menos propenso a
errores. Los espacios en blanco finales ahora se permiten en cadenas numéricas por consistencia
con la forma en que se tratan los espacios en blanco iniciales. Esto afecta principalmente a:
- La función is_numeric()
- Comparaciones de cadena a cadena
- Declaraciones de tipo
- Operaciones de incremento y decremento
El concepto de "cadena numéricamente inicial" ha sido mayormente eliminado; los casos donde esto
se mantiene existen para facilitar la migración. Las cadenas que emitían un
E_NOTICE "A non well-formed numeric value encountered" ahora emitirán un
E_WARNING "A non-numeric value encountered" y todas las cadenas que emitían
un E_WARNING "A non-numeric value encountered" ahora lanzarán un
TypeError. Esto afecta principalmente a:
- Operaciones aritméticas
- Operaciones a nivel de bits
Este cambio de E_WARNING a TypeError también afecta
al E_WARNING "Illegal string offset 'string'" para offsets de cadena
ilegales. El comportamiento de las conversiones explícitas a int/float desde cadenas no ha
cambiado.
-
Los métodos mágicos ahora tendrán sus argumentos y tipos de retorno verificados si los tienen
declarados. Las firmas deben coincidir con la siguiente lista:
__call(string $name, array $arguments): mixed
__callStatic(string $name, array $arguments): mixed
__clone(): void
__debugInfo(): ?array
__get(string $name): mixed
__invoke(mixed $arguments): mixed
__isset(string $name): bool
__serialize(): array
__set(string $name, mixed $value): void
__set_state(array $properties): object
__sleep(): array
__unserialize(array $data): void
__unset(string $name): void
__wakeup(): void
-
Las claves de array de call_user_func_array() ahora se interpretarán como
nombres de parámetros, en lugar de ser silenciosamente ignoradas.
-
Declarar una función llamada assert() dentro de un espacio de nombres ya no
está permitido y emite E_COMPILE_ERROR. La función
assert() está sujeta a un tratamiento especial por parte del motor, lo que
puede llevar a un comportamiento inconsistente al definir una función con espacio de nombres con
el mismo nombre.