PHPCon Poland 2024
Released!
PHP 8.1 es una actualización importante del lenguaje PHP.
Contiene muchas características nuevas y mejoradas, incluyendo enumeraciones, propiedades de solo lectura, sintaxis first-class callable, fibers, tipos de intersección, mejoras de rendimiento y más.

Enumeraciones RFC Doc

PHP < 8.1
class Status
{
const
DRAFT = 'draft';
const
PUBLISHED = 'published';
const
ARCHIVED = 'archived';
}
function
acceptStatus(string $status) {...}
PHP 8.1
enum Status
{
case
Draft;
case
Published;
case
Archived;
}
function
acceptStatus(Status $status) {...}
Use enum en lugar de un conjunto de constantes y obtenga la validación lista para su uso.

Propiedades de solo lectura RFC Doc

PHP < 8.1
class BlogData
{
private
Status $status;

public function
__construct(Status $status)
{
$this->status = $status;
}

public function
getStatus(): Status
{
return
$this->status;
}
}
PHP 8.1
class BlogData
{
public readonly
Status $status;

public function
__construct(Status $status)
{
$this->status = $status;
}
}

Las propiedades de solo lectura no se pueden cambiar después de la inicialización, es decir, después de que se les asigne un valor. Son una excelente manera de modelar objetos de valor y objetos de transferencia de datos.

Sintaxis First-class Callable RFC Doc

PHP < 8.1
$foo = [$this, 'foo'];

$fn = Closure::fromCallable('strlen');
PHP 8.1
$foo = $this->foo(...);

$fn = strlen(...);

Ahora es posible obtener una referencia a cualquier función; esto se llama sintaxis First-class Callable.

Expresión New en constructor RFC

PHP < 8.1
class Service
{
private
Logger $logger;

public function
__construct(
?
Logger $logger = null,
) {
$this->logger = $logger ?? new NullLogger();
}
}
PHP 8.1
class Service
{
private
Logger $logger;

public function
__construct(
Logger $logger = new NullLogger(),
) {
$this->logger = $logger;
}
}

Los objetos instanciados pueden ahora se utilizados como parámetros por defecto, así como variables estáticas, constantes globales, así como argumentos de atributos.

Esto efectivamente permite usar atributos anidados.

PHP < 8.1
class User
{
/**
* @Assert\All({
* @Assert\NotNull,
* @Assert\Length(min=5)
* })
*/
public string $name = '';
}
PHP 8.1
class User
{
#[
\Assert\All(
new
\Assert\NotNull,
new
\Assert\Length(min: 5))
]
public
string $name = '';
}

Tipos de intersección pura RFC Doc

PHP < 8.1
function count_and_iterate(Iterator $value) {
if (!(
$value instanceof Countable)) {
throw new
TypeError('value must be Countable');
}

foreach (
$value as $val) {
echo
$val;
}

count($value);
}
PHP 8.1
function count_and_iterate(Iterator&Countable $value) {
foreach (
$value as $val) {
echo
$val;
}

count($value);
}

Utilice tipos de intersección cuando un valor necesite resolver varias restricciones de tipado al mismo tiempo.

Actualmente no es posible mezclar tipos de intersección y unión como A&B|C.

Tipo de retorno Never RFC Doc

PHP < 8.1
function redirect(string $uri) {
header('Location: ' . $uri);
exit();
}

function
redirectToLoginPage() {
redirect('/login');
echo
'Hello'; // <- dead code
}
PHP 8.1
function redirect(string $uri): never {
header('Location: ' . $uri);
exit();
}

function
redirectToLoginPage(): never {
redirect('/login');
echo
'Hello'; // <- dead code detected by static analysis
}

Una función o método declarado con el tipo never indica que no devolverá un valor y producirá una excepción o finalizará la ejecución del script con una llamada de die(), exit(), trigger_error(), o similar.

Constantes de clase final RFC Doc

PHP < 8.1
class Foo
{
public const
XX = "foo";
}

class
Bar extends Foo
{
public const
XX = "bar"; // No error
}
PHP 8.1
class Foo
{
final public const
XX = "foo";
}

class
Bar extends Foo
{
public const
XX = "bar"; // Fatal error
}

Es posible declarar la constante final en la clase, para que no puedan ser sobreescrita en las clases heredadas.

Notación numérica octal explícita RFC Doc

PHP < 8.1
016 === 16; // false because `016` is octal for `14` and it's confusing
016 === 14; // true
PHP 8.1
0o16 === 16; // false — not confusing with explicit notation
0o16 === 14; // true

Ahora es posible escribir números octales con el prefijo explícito 0o.

Fibers RFC Doc

PHP < 8.1
$httpClient->request('https://example.com/')
->
then(function (Response $response) {
return
$response->getBody()->buffer();
})
->
then(function (string $responseBody) {
print
json_decode($responseBody)['code'];
});
PHP 8.1
$response = $httpClient->request('https://example.com/');
print
json_decode($response->getBody()->buffer())['code'];

Fibers es la forma primitiva para la implementación ligera de concurrencia. Son un medio para crear bloques de código que se puedan pausarse y reanudarse como generadores (Generators), pero desde cualquier lugar de la pila. Los Fibers en sí mismo, no proporcionan la concurrecia mágicamente, todavía se necesita tener un bucle de eventos. Sin embargo, permiten que las implementaciones de bloqueo y no-bloqueo compartan la misma API.

Los Fibers permiten deshacerse del código repetitivo visto anteriormente con Promise::then() o las corutinas basadas en el generador (Generator). Las bibliotecas generalmente construirán más abstracciones alrededor de Fibers, por lo que no hay necesidad de interactuar con ellas directamente.

Soporte de desestructuración de Arrays RFC Doc

PHP < 8.1
$arrayA = ['a' => 1];
$arrayB = ['b' => 2];

$result = array_merge(['a' => 0], $arrayA, $arrayB);

// ['a' => 1, 'b' => 2]
PHP 8.1
$arrayA = ['a' => 1];
$arrayB = ['b' => 2];

$result = ['a' => 0, ...$arrayA, ...$arrayB];

// ['a' => 1, 'b' => 2]

PHP soportaba la desestructuración de Arrays, pero solo si el Array tenía keys de tipo integer. Ahora también es posible la desestructuración de Arrays con keys de tipo string.

Mejoras de rendimiento

Aplicación de demostración de Symfony - tiempo de solicitudes
25 ejecuciones consecutivas, 250 solicitudes (seg)
(menos es mejor)

El resultado (en relación con PHP 8.0):

  • La aplicación de demostración de Symfony es 23.0% más rápida
  • Un sitio WordPress es 3.5% más rápido

Características relacionadas con el rendimiento en PHP 8.1:

  • JIT backend para ARM64 (AArch64)
  • Caché heredado (Evite volver a vincular clases en cada solicitud)
  • Resolución rápida de nombres de clases (evita la resolución de nombres en minúscula y la búsqueda vía hash)
  • Mejoras en el rendimiento de timelib and ext/date
  • Mejoras en los iteradores del sistema de archivos SPL
  • Optimización en serialize/unserialize
  • Optimización de algunas funciones internas (get_declared_classes(), explode(), strtr(), strnatcmp(), dechex())
  • Mejoras y correcciones de JIT

Nuevas clases, interfaces y funciones

  • Nuevo atributo #[ReturnTypeWillChange].
  • Nuevas funciones fsync y fdatasync.
  • Nueva función array_is_list.
  • Nuevas funciones para Sodium XChaCha20.

Obsolescencias y la falta de compatibilidad con versiones anteriores

  • Pasar null como parámetro en funciones internas non-nullable queda obsoleto.
  • Tipos de retorno en los métodos de clase integrados de PHP
  • Interfaz Serializable es obsoleta.
  • Las funciones de entidad HTML en/decode procesan comillas simples y son sustituidas por defecto.
  • Restricciones en la variable $GLOBALS.
  • MySQLi: Modo de error predeterminado establecido en excepciones.
  • La conversión implícita incompatible de float a int es obsoleta.
  • Extensión finfo: recursos de file_info migrado a objetos finfo existentes.
  • IMAP: imap resources migrated to IMAP\Connection class objects.
  • Extensión FTP: Recursos de conexión migrados a la clase FTP\Connection.
  • Extensión GD: Los indetificadores de fuentes (Font) migrados a la clase GdFont.
  • LDAP: recursos migrados a las clases LDAP\Connection, LDAP\Result, y LDAP\ResultEntry.
  • PostgreSQL: recursos migrados a las clases PgSql\Connection, PgSql\Result, y PgSql\Lob.
  • Pspell: los recursos de configuración de pspell y pspell han sido migrados a las clases PSpell\Dictionary, PSpell\Config.
To Top