PHP Conference Nagoya 2025
¡Lanzado!
PHP 8.4 es una actualización importante del lenguaje PHP.
Contiene muchas características nuevas, como hooks para propiedades, visibilidad asimétrica, una API DOM actualizada, mejoras de rendimiento, correcciones de errores y limpieza general.

Hooks para Propiedades RFC Documentación

PHP < 8.4
class Locale
{
private
string $languageCode;
private
string $countryCode;

public function
__construct(string $languageCode, string $countryCode)
{
$this->setLanguageCode($languageCode);
$this->setCountryCode($countryCode);
}

public function
getLanguageCode(): string
{
return
$this->languageCode;
}

public function
setLanguageCode(string $languageCode): void
{
$this->languageCode = $languageCode;
}

public function
getCountryCode(): string
{
return
$this->countryCode;
}

public function
setCountryCode(string $countryCode): void
{
$this->countryCode = strtoupper($countryCode);
}

public function
setCombinedCode(string $combinedCode): void
{
[
$languageCode, $countryCode] = explode('_', $combinedCode, 2);

$this->setLanguageCode($languageCode);
$this->setCountryCode($countryCode);
}

public function
getCombinedCode(): string
{
return
\sprintf("%s_%s", $this->languageCode, $this->countryCode);
}
}

$brazilianPortuguese = new Locale('pt', 'br');
var_dump($brazilianPortuguese->getCountryCode()); // BR
var_dump($brazilianPortuguese->getCombinedCode()); // pt_BR
PHP 8.4
class Locale
{
public
string $languageCode;

public
string $countryCode
{
set (string $countryCode) {
$this->countryCode = strtoupper($countryCode);
}
}

public
string $combinedCode
{
get => \sprintf("%s_%s", $this->languageCode, $this->countryCode);
set (string $value) {
[
$this->languageCode, $this->countryCode] = explode('_', $value, 2);
}
}

public function
__construct(string $languageCode, string $countryCode)
{
$this->languageCode = $languageCode;
$this->countryCode = $countryCode;
}
}

$brazilianPortuguese = new Locale('pt', 'br');
var_dump($brazilianPortuguese->countryCode); // BR
var_dump($brazilianPortuguese->combinedCode); // pt_BR
Los hooks para propiedades proporcionan soporte para propiedades calculadas que pueden ser comprendidas nativamente por los IDE y las herramientas de análisis estático, sin necesidad de escribir comentarios docblock que podrían desincronizarse. Además, permiten un preprocesamiento o postprocesamiento fiable de los valores, sin necesidad de comprobar si existe un getter o setter coincidente en la clase.

Visibilidad asimétrica RFC Documentación

PHP < 8.4
class PhpVersion
{
private
string $version = '8.3';

public function
getVersion(): string
{
return
$this->version;
}

public function
increment(): void
{
[
$major, $minor] = explode('.', $this->version);
$minor++;
$this->version = "{$major}.{$minor}";
}
}
PHP 8.4
class PhpVersion
{
public private(
set) string $version = '8.4';

public function
increment(): void
{
[
$major, $minor] = explode('.', $this->version);
$minor++;
$this->version = "{$major}.{$minor}";
}
}
El alcance para escribir en una propiedad ahora se puede controlar independientemente del alcance para leer la propiedad, lo que reduce la necesidad de métodos getter repetitivos para exponer el valor de una propiedad sin permitir modificaciones desde fuera de una clase.

Atributo #[\Deprecated] RFC Documentación

PHP < 8.4
class PhpVersion
{
/**
* @deprecated 8.3 use PhpVersion::getVersion() instead
*/
public function getPhpVersion(): string
{
return
$this->getVersion();
}

public function
getVersion(): string
{
return
'8.3';
}
}

$phpVersion = new PhpVersion();
// No indication that the method is deprecated.
echo $phpVersion->getPhpVersion();
PHP 8.4
class PhpVersion
{
#[
\Deprecated(
message: "use PhpVersion::getVersion() instead",
since: "8.4",
)]
public function
getPhpVersion(): string
{
return
$this->getVersion();
}

public function
getVersion(): string
{
return
'8.4';
}
}

$phpVersion = new PhpVersion();
// Deprecated: Method PhpVersion::getPhpVersion() is deprecated since 8.4, use PhpVersion::getVersion() instead
echo $phpVersion->getPhpVersion();
El nuevo atributo #[\Deprecated] hace que el mecanismo de obsolescencia existente de PHP esté disponible para funciones, métodos y constantes de clase definidas por el usuario.

Nuevas características de ext-dom y soporte para HTML5 RFC RFC Documentación

PHP < 8.4
$dom = new DOMDocument();
$dom->loadHTML(
<<<'HTML'
<main>
<article>PHP 8.4 is a feature-rich release!</article>
<article class="featured">PHP 8.4 adds new DOM classes that are spec-compliant, keeping the old ones for compatibility.</article>
</main>
HTML,
LIBXML_NOERROR,
);

$xpath = new DOMXPath($dom);
$node = $xpath->query(".//main/article[not(following-sibling::*)]")[0];
$classes = explode(" ", $node->className); // Simplified
var_dump(in_array("featured", $classes)); // bool(true)
PHP 8.4
$dom = Dom\HTMLDocument::createFromString(
<<<'HTML'
<main>
<article>PHP 8.4 is a feature-rich release!</article>
<article class="featured">PHP 8.4 adds new DOM classes that are spec-compliant, keeping the old ones for compatibility.</article>
</main>
HTML,
LIBXML_NOERROR,
);

$node = $dom->querySelector('main > article:last-child');
var_dump($node->classList->contains("featured")); // bool(true)

Nueva API DOM que incluye soporte conforme a los estándares para el análisis de documentos HTML5, corrige varios errores de cumplimiento antiguos en el comportamiento de la funcionalidad DOM, y añade varias funciones para hacer más conveniente trabajar con documentos.

La nueva API DOM está disponible dentro del espacio de nombres Dom. Los documentos que utilizan la nueva API DOM pueden ser creados utilizando las clases Dom\HTMLDocument y Dom\XMLDocument.

API de objetos para BCMath RFC

PHP < 8.4
$num1 = '0.12345';
$num2 = 2;
$result = bcadd($num1, $num2, 5);

echo
$result; // '2.12345'
var_dump(bccomp($num1, $num2) > 0); // false
PHP 8.4
use BcMath\Number;

$num1 = new Number('0.12345');
$num2 = new Number('2');
$result = $num1 + $num2;

echo
$result; // '2.12345'
var_dump($num1 > $num2); // false

El nuevo objeto BcMath\Number permite el uso orientado a objetos y operadores matemáticos estándar cuando se trabaja con números de precisión arbitraria.

Estos objetos son inmutables e implementan la interfaz Stringable, por lo que se pueden usar en contextos de cadena como echo $num.

Nuevas funciones array_*() RFC

PHP < 8.4
$animal = null;
foreach ([
'dog', 'cat', 'cow', 'duck', 'goose'] as $value) {
if (
str_starts_with($value, 'c')) {
$animal = $value;
break;
}
}

var_dump($animal); // string(3) "cat"
PHP 8.4
$animal = array_find(
[
'dog', 'cat', 'cow', 'duck', 'goose'],
static fn (
string $value): bool => str_starts_with($value, 'c'),
);

var_dump($animal); // string(3) "cat"
Nuevas funciones disponibles: array_find(), array_find_key(), array_any() y array_all().

Subclases específicas del driver PDO RFC

PHP < 8.4
$connection = new PDO(
'sqlite:foo.db',
$username,
$password,
);
// object(PDO)

$connection->sqliteCreateFunction(
'prepend_php',
static fn (
$string) => "PHP {$string}",
);

$connection->query('SELECT prepend_php(version) FROM php');
PHP 8.4
$connection = PDO::connect(
'sqlite:foo.db',
$username,
$password,
);
// object(Pdo\Sqlite)

$connection->createFunction(
'prepend_php',
static fn (
$string) => "PHP {$string}",
);
// Does not exist on a mismatching driver.

$connection->query('SELECT prepend_php(version) FROM php');
Las nuevas subclases Pdo\Dblib, Pdo\Firebird, Pdo\MySql, Pdo\Odbc, Pdo\Pgsql y Pdo\Sqlite de PDO ahora están disponibles.

new MyClass()->method() sin paréntesis RFC Documentación

PHP < 8.4
class PhpVersion
{
public function
getVersion(): string
{
return
'PHP 8.3';
}
}

var_dump((new PhpVersion())->getVersion());
PHP 8.4
class PhpVersion
{
public function
getVersion(): string
{
return
'PHP 8.4';
}
}

var_dump(new PhpVersion()->getVersion());
Las propiedades y métodos de un objeto recién instanciado ahora se pueden acceder sin envolver la expresión new entre paréntesis.

Nuevas Clases, Interfaces y Funciones

  • Nuevos Objetos Lazy.
  • Nueva implementación JIT basada en el marco IR.
  • Nueva función request_parse_body().
  • Nuevas funciones: bcceil(), bcdivmod(), bcfloor() y bcround().
  • Nuevo enum RoundingMode para round() con 4 nuevos modos de redondeo: TowardsZero, AwayFromZero, NegativeInfinity y PositiveInfinity.
  • Nuevos métodos: DateTime::createFromTimestamp(), DateTime::getMicrosecond(), DateTime::setMicrosecond(), DateTimeImmutable::createFromTimestamp(), DateTimeImmutable::getMicrosecond(), y DateTimeImmutable::setMicrosecond().
  • Nuevas funciones: mb_trim(), mb_ltrim(), mb_rtrim(), mb_ucfirst(), y mb_lcfirst().
  • Nuevas funciones: pcntl_getcpu(), pcntl_getcpuaffinity(), pcntl_getqos_class(), pcntl_setns() y pcntl_waitid().
  • Nuevos métodos: ReflectionClassConstant::isDeprecated(), ReflectionGenerator::isClosed(), y ReflectionProperty::isDynamic().
  • Nuevas funciones: http_get_last_response_headers(), http_clear_last_response_headers() y fpow().
  • Nuevos métodos: XMLReader::fromStream(), XMLReader::fromUri(), XMLReader::fromString(), XMLWriter::toStream(), XMLWriter::toUri() y XMLWriter::toMemory().
  • Nueva función grapheme_str_split().

Deprecaciones y cambios en compatibilidad retroactiva

  • Las extensiones IMAP, OCI8, PDO_OCI y pspell han sido desagregadas y movidas a PECL.
  • Los tipos de parámetros implícitamente nulos ahora están en desuso.
  • Usar _ como nombre de clase ahora está en desuso.
  • Elevar cero a la potencia de un número negativo ahora está en desuso.
  • Pasar un modo inválido a round() lanza un ValueError.
  • Las constantes de clase de las extensiones date, intl, pdo, reflection, spl, sqlite, xmlreader ahora tienen tipos.
  • La clase GMP ahora es final.
  • Los constantes MYSQLI_SET_CHARSET_DIR, MYSQLI_STMT_ATTR_PREFETCH_ROWS, MYSQLI_CURSOR_TYPE_FOR_UPDATE, MYSQLI_CURSOR_TYPE_SCROLLABLE, y MYSQLI_TYPE_INTERVAL han sido eliminadas.
  • Las funciones mysqli_ping(), mysqli_kill(), mysqli_refresh(), los métodos mysqli::ping(), mysqli::kill(), mysqli::refresh(), y los constantes MYSQLI_REFRESH_* están en desuso.
  • stream_bucket_make_writeable() y stream_bucket_new() ahora devuelven una instancia de StreamBucket en lugar de stdClass.
  • Cambio en el comportamiento de exit().
  • El constante E_STRICT está en desuso.
To Top