PHP 8.5 es una actualización importante del lenguaje PHP, con nuevas características que incluyen la extensión URI, el operador Pipe y soporte para modificar propiedades al clonar.
Más rápido, limpio y construido para desarrolladores.
PHP 8.5 añade una extensión URI integrada para analizar, normalizar y manejar URLs siguiendo los estándares RFC 3986 y WHATWG URL.
El operador |> permite encadenar callables de izquierda a derecha, pasando valores suavemente a través de múltiples funciones sin variables intermedias.
Clona objetos y actualiza propiedades con la nueva sintaxis clone(), simplificando el patrón en clases readonly.
El atributo #[\NoDiscard] advierte cuando un valor de retorno no se usa, ayudando a prevenir errores y mejorando la seguridad.
Los closures estáticos y callables de primera clase ahora pueden usarse en expresiones constantes, como parámetros de atributos.
Los handles ahora pueden persistir a través de múltiples peticiones PHP, evitando el costo de inicialización repetida de conexiones a los mismos hosts.
La nueva extensión URI proporciona APIs para analizar y modificar de forma segura URIs y URLs de acuerdo con los estándares RFC 3986 y WHATWG URL.
Desarrollado por las librerías uriparser (RFC 3986) y Lexbor (WHATWG URL).
Aprende más sobre esta característica en el artículo de The PHP Foundation.
$components = parse_url('https://php.net/releases/8.4/en.php');
var_dump($components['host']);
// string(7) "php.net"use Uri\Rfc3986\Uri;
$uri = new Uri('https://php.net/releases/8.5/en.php');
var_dump($uri->getHost());
// string(7) "php.net"El operador pipe permite encadenar llamadas a funciones sin tener que lidiar con variables intermedias. Esto permite reemplazar muchas "llamadas anidadas" con una cadena que se puede leer hacia adelante, en lugar de hacerlo de adentro hacia afuera.
Aprende más sobre esta característica en el artículo de The PHP Foundation.
$title = ' PHP 8.5 Released ';
$slug = strtolower(
str_replace('.', '',
str_replace(' ', '-',
trim($title)
)
)
);
var_dump($slug);
// string(15) "php-85-released"$title = ' PHP 8.5 Released ';
$slug = $title
|> trim(...)
|> (fn($str) => str_replace(' ', '-', $str))
|> (fn($str) => str_replace('.', '', $str))
|> strtolower(...);
var_dump($slug);
// string(15) "php-85-released"Ahora es posible actualizar propiedades durante la clonación de objetos pasando un array asociativo a la función clone(). Esto permite un soporte directo en las clases readonly.
readonly class Color
{
public function __construct(
public int $red,
public int $green,
public int $blue,
public int $alpha = 255,
) {}
public function withAlpha(int $alpha): self
{
$values = get_object_vars($this);
$values['alpha'] = $alpha;
return new self(...$values);
}
}
$blue = new Color(79, 91, 147);
$transparentBlue = $blue->withAlpha(128);readonly class Color
{
public function __construct(
public int $red,
public int $green,
public int $blue,
public int $alpha = 255,
) {}
public function withAlpha(int $alpha): self
{
return clone($this, [
'alpha' => $alpha,
]);
}
}
$blue = new Color(79, 91, 147);
$transparentBlue = $blue->withAlpha(128);Al agregar el atributo #[\NoDiscard] a una función, PHP verificará si el valor devuelto se consume y emitirá una advertencia si no lo es. Esto permite mejorar la seguridad de APIs donde el valor devuelto es importante, pero se podría olvidar usar el valor de retorno por accidente.
El cast (void) puede usarse para indicar que un valor no se usa intencionalmente.
function getPhpVersion(): string
{
return 'PHP 8.4';
}
getPhpVersion(); // No warning#[\NoDiscard]
function getPhpVersion(): string
{
return 'PHP 8.5';
}
getPhpVersion();
// Warning: The return value of function getPhpVersion() should
// either be used or intentionally ignored by casting it as (void)Los closures estáticos y callables de primera clase ahora pueden usarse en expresiones constantes. Esto incluye parámetros de atributos, valores predeterminados de propiedades y parámetros, y constantes.
final class PostsController
{
#[AccessControl(
new Expression('request.user === post.getAuthor()'),
)]
public function update(
Request $request,
Post $post,
): Response {
// ...
}
}A diferencia de curl_share_init(), los handles creados por curl_share_init_persistent() no serán destruidos al final de la petición PHP. Si se encuentra un handle persistente compartido con el mismo conjunto de opciones compartidas, será reutilizado, evitando el costo de inicializar handles cURL de nuevo.
$sh = curl_share_init();
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT);
$ch = curl_init('https://php.net/');
curl_setopt($ch, CURLOPT_SHARE, $sh);
curl_exec($ch);Las funciones array_first() y array_last() devuelven el primer o último valor de un array, respectivamente. Si el array está vacío, se devuelve null (facilitando su usabilidad con el operador ??).
$lastEvent = $events === []
? null
: $events[array_key_last($events)];$lastEvent = array_last($events);#[\Override] ahora puede aplicarse a propiedades.#[\Deprecated] puede usarse en traits y constantes.final usando la promoción de propiedades en constructores.Closure::getCurrent() para simplificar la recursión en funciones anónimas.setcookie() y setrawcookie() ahora soportan la clave "partitioned".get_error_handler() y get_exception_handler() están disponibles.Dom\Element::getElementsByClassName() y Dom\Element::insertAdjacentHTML() están disponibles.grapheme_levenshtein().#[\DelayedTargetValidation] puede usarse para suprimir errores en tiempo de compilación de atributos del núcleo y extensiones que se usan en destinos inválidos.shell_exec() ha sido deprecado.(boolean), (integer), (double) y (binary) han sido deprecados. Use (bool), (int), (float) y (string) en su lugar, respectivamente.disable_classes ha sido eliminada ya que causa que se rompan varias suposiciones del motor.case con punto y coma en lugar de dos puntos ha sido deprecado.null como offset en un array o al llamar array_key_exists() ahora está deprecado. Use una cadena vacía en su lugar.class_alias().__sleep() y __wakeup() han sido deprecados. Los métodos mágicos __serialize() y __unserialize() deben usarse en su lugar.NAN a otros tipos.null) usando [] o list() ahora emite una advertencia.int si no pueden representarse como uno.