Salvo mención contraria en esta sección, cada nueva » función, » clase, interfaz, enumeración, o » constante puede provocar el lanzamiento de una excepción de redeclaración Error.
    Las construcciones de lenguaje exit() (y die())
    ahora se comportan más como una función.
    Esto significa que ahora pueden pasarse como callables,
    
    son afectadas por la instrucción strict_types,
    y ahora realizan las coerciones de tipo habituales en lugar de convertir
    cualquier valor no entero en una cadena.
   
En consecuencia, pasar tipos no válidos a exit() y die() ahora siempre provoca el lanzamiento de una excepción TypeError.
    Encontrar una recursión al comparar ahora provoca una
    excepción Error en lugar de un error fatal
    E_ERROR.
   
    La modificación indirecta de propiedades de solo lectura en __clone()()
    ya no está permitida, por ejemplo, $ref = &$this->readonly.
    Ya estaba prohibido para la inicialización de solo lectura, y era un
    descuido en la implementación de la "reinicialización de solo lectura al clonar".
   
    Las constantes PHP_DEBUG y PHP_ZTS
    ahora son de tipo bool.
    Anteriormente, eran de tipo int.
   
El nombre de los archivos volcados y de los archivos creados por la función tempnam() ahora es más largo en 13 bytes. La longitud total sigue dependiendo de la plataforma.
Las siguientes clases de extensión ahora declaran un tipo en sus constantes:
   Varios resources han sido migrados a objetos.
   La verificación del valor de retorno con is_resource()
   debe ser reemplazada por verificaciones de false, a menos que se indique lo contrario.
  
    Las funciones DBA ahora aceptan y devuelven
    Dba\Connection en lugar de
    resources dba_connection.
   
    Las funciones ODBC ahora aceptan y devuelven
    Odbc\Result en lugar de
    resources odbc_result.
   
    Las funciones ODBC ahora aceptan y devuelven
    Odbc\Connection en lugar de
    resources odbc_connection.
   
    La propiedad SoapClient::$httpurl ahora es un objeto
    Soap\Url en lugar de una
    resource soap_url.
    Las verificaciones con is_resource() (por ejemplo
    is_resource($client->httpurl)) deben ser reemplazadas por verificaciones de null (por ejemplo $client->httpurl !== null).
   
    La propiedad SoapClient::$sdl ahora es un objeto
    Soap\Sdl en lugar de una
    resource soap_sdl.
    Las verificaciones con is_resource() (por ejemplo
    is_resource($client->sdl)) deben ser reemplazadas por verificaciones de null (por ejemplo $client->sdl !== null).
   
Se han añadido nuevas alertas y excepciones para señalar errores de programación, es decir, valores no válidos proporcionados como argumentos.
    curl_multi_select() ahora lanza una
    ValueError si el parámetro
    timeout es inferior a
    0 o superior a PHP_INT_MAX.
   
    imagejpeg(), imagewebp(), imagepng(), imageavif()
    ahora lanzan una ValueError si se pasa una
    quality no válida.
   
    imageavif() ahora lanza una
    ValueError si se pasa un parámetro
    speed no válido.
   
    imagescale() ahora lanza una
    ValueError si los parámetros
    width o height
    están fuera de los límites.
   
    imagescale() ahora lanza una
    ValueError si se pasa un valor de
    mode no válido.
   
    imagefilter() ahora lanza una
    ValueError con el filtro
    IMG_FILTER_SCATTER si los parámetros
    sub o plus
    están fuera de los límites.
   
    bind_textdomain_codeset(), textdomain(), d()*gettext()
    ahora lanzan una ValueError si se pasa un
    domain no válido.
   
resourcebundle_get(), ResourceBundle::get(), y el acceso a índices en un ResourceBundle ahora lanzan:
    IntlDateFormatter::__construct() lanza una
    ValueError si el
    locale es no válido.
   
    NumberFormatter::__construct() lanza una
    ValueError si el
    locale es no válido.
   
    mb_encode_numericentity() y
    mb_decode_numericentity() ahora verifican que
    map está compuesto únicamente por enteros,
    si no es el caso, se lanza una ValueError.
   
    mb_http_input() ahora lanza una
    ValueError si el type
    es no válido.
   
    mb_http_output() ahora verifica que
    encoding no contiene caracteres nulos,
    si es el caso, se lanza una ValueError.
   
    odbc_fetch_row() devuelve false cuando
    row es inferior o igual a 0.
    Ahora se emite una alerta en este caso.
   
Las funciones pcntl_sigprocmask(), pcntl_sigwaitinfo(), y pcntl_sigtimedwait() ahora lanzan:
signals está vacío
      (excepto para pcntl_sigprocmask() si el
      mode es SIG_SETMASK)
     signals no es un entero
     signals no es un número de señal válido
     
    La función pcntl_sigprocmask() ahora lanza una
    ValueError si el
    mode no es uno de los SIG_BLOCK,
    SIG_UNBLOCK, o SIG_SETMASK.
   
La función pcntl_sigtimedwait() ahora lanza:
seconds es inferior a 0
     nanoseconds es inferior a 0
      o superior a 1e9
     seconds y nanoseconds
      son 0
     Llamar a simplexml_import_dom() con un objeto no-XML ahora lanza una TypeError en lugar de una ValueError.
    La función round() ahora verifica el valor del
    mode y lanza una
    ValueError para modos no válidos.
    Anteriormente, los modos no válidos se interpretaban como
    PHP_ROUND_HALF_UP.
   
    La función str_getcsv() ahora lanza una
    ValueError si los argumentos
    separator y enclosure
    no tienen un byte de largo, o si el argumento escape
    no tiene un byte de largo o es una cadena vacía.
    Esto alinea el comportamiento para que sea idéntico al de
    fputcsv() y fgetcsv().
   
    La función php_uname() ahora lanza una
    ValueError si el
    mode es no válido.
   
    La opción "allowed_classes" para
    unserialize() ahora lanza
    TypeError y
    ValueError si no es un
    array de nombres de clase.
   
Pasar un codificado de caracteres no válido a XMLReader::open() o XMLReader::XML() ahora lanza una ValueError.
Pasar una cadena que contiene bytes nulos anteriormente emitía una alerta y ahora lanza una ValueError.
Pasar una cadena que contiene bytes nulos anteriormente emitía una alerta y ahora lanza una ValueError.
XSLTProcessor::setParameter() ahora lanza una ValueError cuando sus argumentos contienen bytes nulos. Esto nunca funcionó correctamente en primer lugar, por lo que ahora se lanza una excepción.
Llamar a XSLTProcessor::importStylesheet() con un objeto no-XML ahora lanza una TypeError en lugar de una ValueError.
El fallo al llamar a una función de devolución de llamada PHP durante la evaluación ahora lanza una excepción en lugar de emitir una alerta.
   number símbolos en formatos relativos
   aceptan nuevamente múltiples signos, por ejemplo, +-2.
  
   Algunos métodos DOM anteriormente devolvían false o una
   DOMException PHP_ERR
   si no se podía agregar un nuevo nodo.
   Ahora siempre lanzan una DOMException
   INVALID_STATE_ERR.
   Esta situación es extremadamente improbable y la probabilidad de verse afectado
   es baja.
   En consecuencia, DOMImplementation::createDocument()
   ahora tiene un tipo de retorno provisional de DOMDocument
   
   en lugar de DOMDocument|false.
  
Anteriormente, los objetos DOMXPath podían ser clonados, pero resultaban en un objeto inutilizable. Esto ya no es posible, y clonar un objeto DOMXPath ahora lanza una Error.
El método DOMImplementation::getFeature() ha sido eliminado.
La clase GMP ahora es final y ya no puede ser extendida.
En caso de cadenas no válidas (aquellas con errores de codificación), mb_substr() ahora interpreta los índices de caracteres de la misma manera que la mayoría de las otras funciones mbstring. Esto significa que los índices de caracteres devueltos por mb_strpos() pueden pasarse a mb_substr().
Para las cadenas SJIS-Mac (MacJapanese), los índices de caracteres pasados a mb_substr() ahora se refieren a los índices de los puntos de código Unicode que se producen cuando la cadena se convierte a Unicode. Esto es significativo porque aproximadamente 40 caracteres SJIS-Mac se convierten en una secuencia de múltiples puntos de código Unicode.
   La constante no utilizada y no documentada
   MYSQLI_SET_CHARSET_DIR ha sido eliminada.
  
   La constante MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH ha sido
   eliminada. Esta funcionalidad no está disponible con mysqlnd.
  
   Las constantes MYSQLI_STMT_ATTR_CURSOR_TYPE y
   MYSQLI_STMT_ATTR_PREFETCH_ROWS han sido eliminadas.
   Estas funcionalidades nunca fueron implementadas,
   ni con mysqlnd ni con libmysql.
  
   La constante no utilizada MYSQLI_TYPE_INTERVAL, que actualmente es un stub y un alias para MYSQLI_TYPE_ENUM,
   ha sido eliminada.
   
  
   El código de error reportado para los tiempos de espera del servidor MySQL ha cambiado de
   2006 a 4031 para las versiones del servidor
   MySQL 8.0.24 y superiores.
  
   El valor máximo de la configuración
   opcache.interned_strings_buffer
   en arquitecturas de 64 bits ahora es 32767.
   Anteriormente, era 4095.
  
    El valor por defecto de la configuración JIT ha cambiado de
    opcache.jit=tracing
    y opcache.jit_buffer_size=0
    a opcache.jit=disable
    y opcache.jit_buffer_size=64M, respectivamente.
   
Esto no afecta el comportamiento observable por defecto, porque el JIT sigue estando desactivado por defecto. Sin embargo, ahora se desactiva a través de la configuración opcache.jit, en lugar de opcache.jit_buffer_size. Esto puede afectar a los usuarios que anteriormente habían activado el JIT a través de opcache.jit_buffer_size exclusivamente, sin especificar también un modo JIT usando opcache.jit. Para habilitar la compilación JIT, defina el valor de configuración opcache.jit en consecuencia.
Si la compilación JIT está habilitada, PHP ahora finalizará con un error fatal al iniciar si la inicialización del compilador JIT falla por cualquier motivo.
   Las funciones pcntl_sigprocmask(),
   pcntl_sigwaitinfo(), y
   pcntl_sigtimedwait() ahora devuelven sistemáticamente
   false en caso de fallo.
   En algunos casos anteriores, podían devolver el valor -1.
  
   La versión de pcre2lib incluida se ha actualizado a la versión 10.44.
   Esto significa que {,3} ahora se reconoce como un cuantificador en lugar de un texto.
   Además, la significación de algunas clases de caracteres en modo UCP ha cambiado.
   Consulte el » registro de cambios de PCRE2
   para obtener un registro de cambios completo.
  
   Los atributos Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIER y
   Pdo\Dblib::ATTR_DATETIME_CONVERT ahora actúan como atributos booleanos en lugar de atributos enteros.
   Por lo tanto, definir el atributo a través de PDO::setAttribute()
   y recuperarlo a través de PDO::getAttribute() espera y devuelve un bool.
  
   El atributo PDO::ATTR_AUTOCOMMIT ahora actúa como un
   atributo booleano en lugar de un atributo entero.
   Por lo tanto, definir el atributo a través de PDO::setAttribute()
   y recuperarlo a través de PDO::getAttribute() espera y devuelve un bool.
  
La extensión ahora expone ciertas API C++ de Firebird, por lo que la construcción de esta extensión ahora requiere un compilador C++. Además, la extensión ahora debe compilarse contra fbclient 3.0 o superior.
   Los atributos PDO::ATTR_AUTOCOMMIT
   PDO::ATTR_EMULATE_PREPARES, y
   PDO::MYSQL_ATTR_DIRECT_QUERY ahora actúan como atributos booleanos en lugar de atributos enteros.
   Por lo tanto, definir el atributo a través de PDO::setAttribute()
   y recuperarlo a través de PDO::getAttribute() espera y devuelve un bool.
  
La información de conexión DSN, cuando se define, ahora tiene prioridad sobre los argumentos del constructor PDO, estando más cerca de lo que indica la documentación.
Establecer un valor no positivo para session.gc_divisor o un valor negativo para session.gc_probability emite ahora una advertencia.
SimpleXMLElement no es solo una representación de un elemento XML, sino que también es un RecursiveIterator. Antes de PHP 8.4.0, algunos de sus métodos (por ejemplo, SimpleXMLElement::asXML() o SimpleXMLElement::getName()) y la conversión de tales instancias a string reinicializaban implícitamente el iterador.
Esto podía provocar bucles infinitos no intencionados porque el iterador se reinicializaba. Por ejemplo:
<?php
$xmlString = "<root><a><b>1</b><b>2</b><b>3</b></a></root>";
$xml = simplexml_load_string($xmlString);
$nodes = $xml->a->b;
foreach ($nodes as $nodeData) {
    echo "nodeData: " . $nodeData . "\n";
    $xml = $nodes->asXml();
}causaba un bucle infinito.
nodeData: 1 nodeData: 2 nodeData: 2 nodeData: 2 nodeData: 2 nodeData: 2 nodeData: 2 // ...
Sin embargo, este comportamiento ha sido corregido, y un SimpleXMLElement ya no reinicializará implícitamente el iterador, a menos que se restablezca explícitamente a cero. Esto significa que el ejemplo anterior ahora daría:
nodeData: 1 nodeData: 2 nodeData: 3
   SoapClient::$typemap ahora es un array
   en lugar de una resource.
   Las verificaciones con is_resource() (es decir,
   is_resource($client->typemap)) deben ser reemplazadas por verificaciones de null (es decir, $client->typemap !== null).
  
La extensión SOAP ha adquirido una dependencia opcional de la extensión session. Si PHP se compila sin la extensión session y con la opción de configuración --enable-rtld-now activada, se producirán errores de inicio si también se utiliza la extensión SOAP. Para resolver este problema, no utilice rtld-now o cargue la extensión session.
   Al usar strcspn() con
   characters siendo una cadena vacía,
   ahora se devuelve la longitud de la cadena en lugar de detenerse
   en el primer byte nulo.
   
  
http_build_query() ahora maneja correctamente las enumeraciones
stream_bucket_make_writeable() y stream_bucket_new() ahora devuelven una instancia de StreamBucket en lugar de una instancia de stdClass.
Los errores en el constructor ahora lanzan excepciones en lugar de emitir advertencias y tener un objeto roto.
   Las funciones xml_set_()*_handler()
   ahora declaran y verifican una firma
   efectiva de callable|string|null para los
   parámetros handler.
   Además, los valores de tipo string que corresponden a nombres de método,
   de objeto definido con xml_set_object() ahora se verifican para
   ver si el método existe en la clase del objeto previamente pasado.
   Esto significa que xml_set_object() ahora siempre debe
   ser llamada antes de definir nombres de método como callable.
   Pasar una cadena vacía para deshabilitar el manejador sigue estando permitido,
   pero está desaprobado.
  
Además, con xml_set_object() y el paso de cadenas no-callable está desaprobado. Se recomienda reemplazar tales instancias con un callable que se refiera directamente al método.
