NOVEDADES DEL NUEVO PHP 8
¿Debería actualizar mi servidor a PHP 8?
La recomendación es que aún no lo hagas. Entre la última versión de PHP 7 y la nueva versión de PHP 8 han habido cambios importantes, que como mínimo te obligarán a realizar algunas modificaciones en tus scripts en producción, y no es seguro que estés preparado para ponerte a reprogramar varios de los problemas que surjan por ello.
UPDATE DE ENERO 2021: Habiendo pasado las etapas de testing de rendimiento y seguridad en nuestro laboratorio, PHP 8 ya se encuentra disponible.
Cambios y novedades de PHP 8
Algo que nos pareció genial y estamos ansiosos de contarte es que PHP 8 también trae un conjunto de nuevas características como el compilador JIT, union types y nuevos atributos. Profundizaremos en esto a lo largo de esta nota. ¡Empecemos!
Compilador JIT
El compilador JIT (Just In Time, o “justo a tiempo”), promete importantes mejoras de rendimiento, aunque no siempre aplicaría en el contexto de las aplicaciones web, pero podría traer algunos cambios positivos si es usado correctamente. JIT es una técnica que compilará partes del código durante la ejecución, de modo que se pueda usar una versión precompilada del script. Piensa en ello como una versión en caché de parte del código.
El compilador JIT de PHP 8 tiene un monitor que observará el código mientras se ejecuta. Cuando este monitor detecta partes del código que se vuelven a ejecutar una y otra vez, las marcará como “almacenables en caché” de acuerdo a su frecuencia de ejecución. Estas partes de código de uso frecuente, se compilarán en código de máquina ya optimizado, y se utilizarán sobre la marcha en lugar del código real, lo que haría que en aplicaciones demasiado pesadas, ganes tiempo de ejecución y carga del servidor.
Union types
Dada la naturaleza de PHP, hay muchos casos en los que los union types o tipos de unión pueden ser útiles. Los union types son un mecanismo que permite especificar diferentes tipos para una misma variable, parámetro de una función o como resultado devuelto. Un ejemplo sería:
public function test(Test|Bar $input): int|float;
Named arguments
Los Named arguments o argumentos con nombre, permiten pasar valores a una función, especificando su valor para evitar tener en cuenta el orden, y también se pueden omitir otros parámetros.
function test(string $a, string $b, ?string $c = null, ?string $d = null) { /* … */ } test( b: 'value b', a: 'value a', d: 'value d', );
Attributes
Los atributos, comúnmente conocidos como anotaciones, ofrecen una forma rápida de agregar metadatos a las clases, sin tener que analizar docblocks y parsearlo. Con PHP 8, podrás especificar atributos y anotaciones sin tener que recurrir a bloques de comentarios.
use App\Attributes\ExampleAttribute; #[ExampleAttribute] class Test { #[ExampleAttribute] public const Test = 'test'; #[ExampleAttribute] public $x; #[ExampleAttribute] public function test(#[ExampleAttribute] $bar) { } }
Información completa acerca de los atributos de PHP en este enlace.
Match expression
Podría llamarle a Match expression o “expresión de coincidencia” el hermano mayor de la expresión: “switch” (la expresión nueva es “match”), y puede devolver valores sin declarar, puede combinar condiciones, y usa comparaciones de tipos estrictas como lo ves en este pedazo de código:
$result = match($input) { 0 => "hello", '1', '2', '3' => "world", };
Constructor property promotion
Constructor property promotion sirve para crear objetos de value objects y data transfer objects. En lugar de especificar propiedades de clase PHP, ahora puede combinarlas en una sola. Lo que antes hacías así:
class Money { public Currency $currency; public int $amount; public function __construct( Currency $currency, int $amount, ) { $this->currency = $currency; $this->amount = $amount; } }
Ahora puedes hacerlo de esta hora manera:
class Money { public function __construct( public Currency $currency, public int $amount, ) {} }
Nuevo retorno “static”
Si bien ya era posible devolver “static”, no era tenido en cuenta como retorno válido. Ahora sí con PHP 8. Confiamos en que esta característica que será útil para muchos desarrolladores.
class TestA { public function test(): static { return new static(); } }
Mixed type
Con el nuevo Mixed type podrás utilizar la función “mixed” para ahorrar mucho tiempo, asignando valores como array, bool, callable, int, float, object, resource y string. El tipo “mixed” también se puede utilizar como parámetro o tipo de propiedad, no solo como tipo de retorno de un valor. Solo ten en cuenta que “mixed” ya incluye “null”, con lo que te llevarás un error como este si lo utilizas, así que si algo así te ocurre, sabes por dónde revisar.
// Fatal error: Mixed types cannot be nullable, null is already part of the mixed type.
Herencia con métodos privados (Inheritance with private methods)
En anteriores versiones, PHP aplicaba las mismas comprobaciones de herencia en métodos públicos, protegidos y privados. En PHP 8 cambió este comportamiento, por lo que estas comprobaciones de herencia ya no se realizan en métodos privados. Además, el uso de “final private function” tampoco tenía sentido, por lo que ahora se activará un warning de PHP como el que ves aquí debajo.
Warning: Private methods cannot be final as they are never overridden by other classes
Weak maps
Luego de su incorporación en la versión de PHP 7.4, los Weak maps en PHP 8 te permitirán almacenar referencias a objetos, pero sin que sean descartados por el “garbage collector”. Sin duda esto ayudará a administrar la memoria utilizada por el servidor de forma más eficiente almacenando objetos en caché.
class Test { private WeakMap $cache; public function getSomethingWithCaching(object $obj): object { return $this->cache[$obj] ??= $this->computeSomethingExpensive($obj); } }
Se permite “::class” en objetos
Una característica nueva, pequeña pero tal vez útil es que ahora es posible usar “::class” en objetos, en lugar de tener que usar get_class() en ellos. Lo bueno es que funciona de la misma forma que get_class().
$test = new Test(); var_dump($test::class);
Captura de excepciones
Antes de la aparición de PHP, cuando querías capturar una excepción, necesitabas almacenarla primero en una variable. Con “Non-capturing catches”, puedes omitir ese paso.
Antes:
try { // Algo anduvo mal } catch (MiExcepcion $exception) { Log::error("Algo anduvo mal"); }
Ahora:
try { // Algo anduvo mal } catch (MiExcepcion) { Log::error("Algo anduvo mal"); }
Coma final
Ya se podría usar coma (“,”) al llamar a una función en versiones anteriores de PHP, pero ahora se pueden usar al final de la lista de parámetros. En PHP 8 ahora puedes hacer esto:
public function( string $parameterA, int $parameterB, Test $objecttest, ) {}
Nueva función “str_contains”
Para definir si una cadena contiene un string o texto, ya no tienes que recurrir a la función “strpos”. Con “str_contains” puedes hacerlo de esta manera:
if (str_contains('string con muchas palabras', 'palabra')) { /* … */ }
Nueva función fdiv
Más de una vez te has topado con la salida “Nan”. La función “fdiv” es similar a las funciones “fmod” y “intdiv”, pero con la diferencia que permite dividir por “0”.
Ya no se pueden ocultar los “fatal error” de PHP
Es posible cuando actualices tu servidor a PHP 8, este cambio saque a la luz errores que estaban ocultos antes de implementarlo.
Si esto afecta a tu app, puedes configurar tu server PHP con “display_errors=off” antes de ir a producción.
Precedencia de concatenado
Si bien ya está obsoleto en PHP versión 7.4, este cambio ahora entra en vigencia definitiva, y si escribes algo así:
echo "sum: " . $a + $b;
PHP 8 lo interpretará de esta manera:
echo "sum: " . ($a + $b);
Operadores aritméticos
En versiones anteriores se podían aplicar operadores aritméticos en matrices y objetos, pero ya no es posible te y arrojará un error de tipo “TypeError”.