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.
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.
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_BRclass 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_BREl 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.
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}";
}
}class PhpVersion
{
public private(set) string $version = '8.4';
public function increment(): void
{
[$major, $minor] = explode('.', $this->version);
$minor++;
$this->version = "{$major}.{$minor}";
}
}#[\Deprecated]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.
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();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();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.
$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)$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)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.
$num1 = '0.12345';
$num2 = '2';
$result = bcadd($num1, $num2, 5);
echo $result; // '2.12345'
var_dump(bccomp($num1, $num2) > 0); // falseuse BcMath\Number;
$num1 = new Number('0.12345');
$num2 = new Number('2');
$result = $num1 + $num2;
echo $result; // '2.12345'
var_dump($num1 > $num2); // falsearray_*()Nuevas funciones disponibles: array_find(), array_find_key(), array_any() y array_all().
$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"$animal = array_find(
['dog', 'cat', 'cow', 'duck', 'goose'],
static fn(string $value): bool => str_starts_with($value, 'c'),
);
var_dump($animal); // string(3) "cat"Las nuevas subclases Pdo\Dblib, Pdo\Firebird, Pdo\MySql, Pdo\Odbc, Pdo\Pgsql y Pdo\Sqlite de PDO ahora están disponibles.
$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');$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');new MyClass()->method() sin paréntesisLas propiedades y métodos de un objeto recién instanciado ahora se pueden acceder sin envolver la expresión new entre paréntesis.
class PhpVersion
{
public function getVersion(): string
{
return 'PHP 8.3';
}
}
var_dump((new PhpVersion())->getVersion());class PhpVersion
{
public function getVersion(): string
{
return 'PHP 8.4';
}
}
var_dump(new PhpVersion()->getVersion());request_parse_body().bcceil(), bcdivmod(), bcfloor() y bcround().RoundingMode para round() con 4 nuevos modos de redondeo: TowardsZero, AwayFromZero, NegativeInfinity y PositiveInfinity.DateTime::createFromTimestamp(), DateTime::getMicrosecond(), DateTime::setMicrosecond(), DateTimeImmutable::createFromTimestamp(), DateTimeImmutable::getMicrosecond(), y DateTimeImmutable::setMicrosecond().mb_trim(), mb_ltrim(), mb_rtrim(), mb_ucfirst(), y mb_lcfirst().pcntl_getcpu(), pcntl_getcpuaffinity(), pcntl_getqos_class(), pcntl_setns() y pcntl_waitid().ReflectionClassConstant::isDeprecated(), ReflectionGenerator::isClosed(), y ReflectionProperty::isDynamic().http_get_last_response_headers(), http_clear_last_response_headers() y fpow().XMLReader::fromStream(), XMLReader::fromUri(), XMLReader::fromString(), XMLWriter::toStream(), XMLWriter::toUri() y XMLWriter::toMemory().grapheme_str_split()._ como nombre de clase ahora está en desuso.round() lanza un ValueError.date, intl, pdo, reflection, spl, sqlite, xmlreader ahora tienen tipos.GMP ahora es final.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.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.exit().E_STRICT está en desuso.E_USER_ERROR to trigger_error() is now deprecated.