PHP 8.4.1 Released!

Cambios retroincompatibles

Lanzamiento de una excepción al pasar muy pocos argumentos a una función

Anteriormente se emitía una advertencia al invocar funciones definidas por el usuario con muy pocos argumentos. Ahora, esta advertencia ha sido promovida a una excepción de tipo Error. Este cambio solamente se aplica a funciones definidas por el usuario, no a funciones internas. Por ejemplo:

<?php
function test($param){}
test();

El resultado del ejemplo sería algo similar a:

Fatal error: Uncaught ArgumentCountError: Too few arguments to function test(), 0 passed in %s on line %d and exactly 1 expected in %s:%d

Prohibición de llamadas dinámicas a funciones de introspección de alcance

Se han prohibido las llamadas dinámicas a ciertas funciones (de la forma $func() o array_map('extract', ...), etc.). Estas funciones bien inspeccionan o modifican otro ámbito, presentando así un comportamiento ambiguo y poco fiable. Las funciones son las siguientes:

<?php
(function () {
$func = 'func_num_args';
$func();
})();

El resultado del ejemplo sería:

Warning: Cannot call func_num_args() dynamically in %s on line %d

Nombres de clases, interfaces o rasgos no válidos

Los siguientes nombres no se pueden usar como nombres de clases, interfaces o rasgos:

Las conversiones de cadenas numéricas ahora respetan la notación científica

Las operaciones y conversiones de enteros en cadenas de numéricas ahora respetan la notación científica. Esto también incluye la operación 'cast' a (int) y l as siguientes funciones: intval() (donde la base es 10), settype(), decbin(), decoct(), y dechex().

Correcciones al algoritmo mt_rand()

mt_rand() ahora utilizará predeterminadamente la versión corregida del algoritmo Mersenne Twister. Si se confiaba en la salida determinista de mt_srand(), la constante MT_RAND_PHP con la capacidad de preservar la implementación antigua (incorrecta) mediante un segundo parámetro opcional adicional a mt_srand().

rand() es un alias de mt_rand() y srand() de mt_srand()

rand() y srand() ahora son alias de mt_rand() y mt_srand(), respectivamente. Esto significa que la salida de las siguientes funciones ha cambiado: rand(), shuffle(), str_shuffle(), y array_rand().

Rechazar el caracter de control de borrado ASCII en identificadores

El caracter de control de borrado ASCII (0x7F) ya no se puede usar en identificadores que no estén entrecomillados.

error_log cambia con el valor syslog

Si el ajuste ini de error_log se establece a syslog, los niveles de error de PHP se corresponden con los niveles de error de syslog. Esto ofrece un mayor diferenciación en los registros de errores, al contrario que el enfoque anterior, donde todos los errores eran registrados con el nivel 'notice' solamente.

No invocar a destructores en objetos incompletos

Ahora, los destructores nunca son invocados en objetos que lanzan una excepción durante la ejecución de su constructor. En versiones anteriores, este comportamiento dependía de si al objeto se le hacía referencia fuera del constructor (p.ej., mediante el rastreo de una excepción).

Manejo de call_user_func() de argumentos de referencia

call_user_func() ahora generará siempre una advertencia al llamar a funciones que esperan referencias como argumentos. Anteriormente esto dependía de si la llamada era totalmente cualificada.

Además, call_user_func() y call_user_func_array() ya no abortarán la llamada a la función es este caso. La advertencia de "expected reference" (se esperaba una referencia) será emitida, aunque la llamada procederá como siempre.

El operador de índice vacío ya no se admite más para cadenas

La aplicación del operador de índice vacío a una cadena (p.ej. $str[] = $x) lanza un error fatal en lugar de convertirla a un array silenciosamente.

Directivas ini eliminadas

Las siguientes directivas ini han sido eliminadas:

  • session.entropy_file
  • session.entropy_length
  • session.hash_function
  • session.hash_bits_per_character

Cambio en la ordenación de arrays cuando los elementos son creados automáticamente durante asignaciones por referencia

El orden de los elementos de un array ha cambiado cuando estos elementos han sido creados automáticamente mediante 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 7.0:

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

Salida del ejemplo anterior en PHP 7.1:

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

Ordenación de elementos iguales

El algoritmo de ordenación interno se ha mejorado, lo que podría resultar en una ordenación diferente de los elementos que se comparan como iguales.

Nota:

No confíe en el orden de elementos que se comparan como iguales; podría cambiar en cualquier momento.

Mensaje de error para los errores E_RECOVERABLE

El mensaje de error para errores E_RECOVERABLE ha cambiado de "Catchable fatal error" a "Recoverable fatal error".

Parámetro $options de unserialize()

El elemento allowed_classes del parámetro $options de unserialize() ahora está estrictamente tipificado, es decir, si se da un valor distinto a un array o un boolean, unserialize() devuelve false y emite un E_WARNING.

DateTime constructor incorporates microseconds

DateTime y DateTimeImmutable ahora incorporan adecuadamente microsegundos al ser construidos desde el momento actual, ya sea explícitamente o con una cadena relativa(p.ej., "first day of next month"). Esto significa que la simple comparación de dos instancias recién creadas ahora probablemente devuelva false en lugar de true:

<?php
new DateTime() == new DateTime();
?>

Conversión de errores fatales a excepciones Error

En la extensión Date, los datos de serialización inválidos para las clases DateTime o DatePeriod, o el fallo de inicialización de una zona horaria desde datos serializados, ahora lanzarán una excepción Error desde los métodos __wakeup() o __set_state(), en lugar de resultar en un error fatal.

En la extensión DBA, las funciones que modifican datos (como dba_insert()) ahora lanzarán una excepción Error en lugar de emitir un error fatal capturable si la clave no contiene exactamente dos elementos.

En la extensión DOM, un esquema inválido o contextos de validación RelaxNG ahora lanzarán una excepción Error en lugar de resultar en un error fatal. De manera similar, el intento de registrar una clase nodo que no extienda la clase base apropiada, o el intento de leer una propiedad inválida o escribir en una propiedad de solo lectura, también lanzará una excepción Error.

En la extensión IMAP, las direcciones de correo electrónica mayores de 16385 bytes lanzarán una excepción Error en lugar de resultar en un error fatal.

En la extensión Intl, el fallo al invocar al constructor padre en una clase que extiende Collator antes de invocar a los métodos padres ahora lanzará una excepción Error en lugar de resultar en un error fatal recuperable. También, clonar un objeto Transliterator ahora lanzará una excepción Error en caso de fallo al clonar el transliterador interno en lugar de resultar en un error fatal.

En la extensión LDAP, proporcionar un tipo de modificación desconocido a ldap_batch_modify() ahora lanzará una excepción Error en lugar de resultar en un error fatal.

En la extensión bstring, las funciones mb_ereg() y mb_eregi() ahora lanzarán una excepción ParseError si se proporciona una expresión de PHP inválida y se emplea la opción 'e'.

En la extensión Mcrypt, las funciones mcrypt_encrypt() y mcrypt_decrypt() ahora lanzarán una excepción Error en lugar de resultar en un error fatal si mcrypt no puede ser inicializado.

En la extensión mysqli, el intento de leer una propiedad inválidad o escribir en una propiedad de solo lectura ahora lanzará una excepción Error en lugar de resultar en un error fatal.

En la extensión Reflection, el fallo al recuperar un objeto de reflexión o recuperar una propiedad de un objeto ahora lanzará una excepción Error en lugar de resultar en un error fatal.

En la extensión Session, los manejadores de sesiones propios que no devuelvan cadenas para los ID de sesción ahora lanzarán una excepción Error en lugar de resultar en un error fatal cuando una función sea invocada y deba generar un ID de sesión.

En la extensión SimpleXML, la creación de un atributo sin nombre o duplicado ahora lanzará una excepción Error en lugar de resultar en un error fatal.

En la extensión SPL, el intento de clonar un objeto SplDirectory ahora lanzará una excepción Error en lugar de resultar en un error fatal. De forma simiarl, invocar a ArrayIterator::append() cuando se recorre un objeto también lanzará una excepción Error.

En la extensión estándar, la función assert(), al proporcionarle un argumento de cadena a su primer parámetro, ahora lanzará una excepción ParseError en lugar de resultar en un error fatal capturable si el código de PHP no es válido. De forma similar, invocar a forward_static_call() fuera del ámbito de una clase ahora también lanzará una excepción Error.

En la extensión Tidy, la creación manual de un objeto tidyNode ahora lanzará una excepción Error en lugar de resultar en un error fatal.

En la extensión WDDX, una referencia circular al serializar ahora lanzará una excepción Error en lugar de resultar en un error fatal.

En la extensión XML-RPC, una referencia circular al serializar ahora lanzará una instancia de una excepción Error en lugar de resultar en un error fatal.

En la extensión Zip, el método ZipArchive::addGlob() ahora lanzará una excepción Error en lugar de resultar en un error fatal si el soporte para 'glob' no está disponible.

Las variables vinculadas léxicamente no pueden reutilizar nombres

Las variables vinculadas a un cierre mediante el constructor use no pueden utilizar el mismo nombre que cualquier superglobals, $this, o cualquier parámetro. Por ejemplo, todas estas definiciones de funciones resultarán en error fatal:

<?php
$f
= function () use ($_SERVER) {};
$f = function () use ($this) {};
$f = function ($param) use ($param) {};

Cambio del tipo del parámetro de long2ip()

long2ip()() ahora espera un int en vez de un string.

Codificación y decodificación de JSON

El ajuste ini serialize_precision ahora controla la precisión de serialización al codificar 'doubles'.

La decodificación de una clave vacía ahora resulta en un nombre de propiedad vacío, en lugar de _empty_ como nombre de propiedad.

<?php
var_dump
(json_decode(json_encode(['' => 1])));

El resultado del ejemplo sería algo similar a:

object(stdClass)#1 (1) {
  [""]=>
  int(1)
}

Al proporcionar la bandera JSON_UNESCAPED_UNICODE a json_encode(), las secuencias U+2028 y U+2029 ahora son escapadas.

Cambios en la semántica de los parámetros de mb_ereg() y mb_eregi()

El tercer parámetro de las funciones mb_ereg() y mb_eregi() (regs) ahora será establecido a un array vacío si no hubieron coincidencias. Anteriormente, el parametro era modificado.

Eliminación del soporte para el flujo sslv2

El flujo sslv2 se ha eliminado de OpenSSL.

add a note

User Contributed Notes 5 notes

up
46
love at sickpeople dot se
7 years ago
For anyone migrating from 5.x to 7.1:

About "Array ordering when elements are automatically created during by reference assignments has changed" on this page

(http://php.net/manual/en/migration71.incompatible.php#migration71.incompatible.array-order)

The behaviour of 7.1 is THE SAME as of PHP 5. It is only 7.0 that differs.

See https://3v4l.org/frbUc

<?php

$array
= [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
up
34
kees at twekaers dot net
7 years ago
The backwards incompatible change 'The empty index operator is not supported for strings anymore' has a lot more implications than just a fatal error on the following code

<?php
$a
= "";
$a[] = "hello world";
var_dump($a);
?>

This will give a fatal error in 7.1 but will work as expected in 7.0 or below and give you: (no notice, no warning)

array(1) {
[0]=>
string(11) "hello world"
}

However, the following is also changed:

<?php
$a
= "";
$a[0] = "hello world";
var_dump($a);
// 7.1: string(1) "h"
// pre-7.1: array(1) { [0]=> string(11) "hello world" }

$a = "";
$a[5] = "hello world";
var_dump($a);
// 7.1: string(6) " h"
// pre-7.1: array(1) { [0]=> string(11) "hello world" }

?>
up
17
m dot r dot sopacua at gmail dot com
7 years ago
"OMFG! Why was session.hash_function removed?!? Dude!"

https://wiki.php.net/rfc/session-id-without-hashing

There. Saved ya a search.
up
2
mikem at gmail dot com
7 years ago
ArgumentCountError - this modification is the main reason to avoid this version on older projects.
up
0
david at artefactual dot com
5 years ago
Regarding the ArgumentCountError, PHP 7.1+ does still support user functions with a variable number of arguments, using the "func(...$args) {}" syntax, see: https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list
To Top