Raul Jimenez
Experto en Drupal
PHP 8 – ¿Qué mejoras trae?
Como seguro que ya sabéis, el pasado día 26 de noviembre 2020, salió a la luz una nueva versión php 8. Esta versión cuenta con una gran cantidad de cambios y mejoras que nos van ayudará en gran medida a escribir un código más corto y fácil de leer, una mejora de rendimiento y una larga lista de cosas.
Esta versión al ser una versión mayor (Mayor versión) introduce una multitud de cambios y mejoras pero hoy solamente veremos aquellos que considero más relevantes, así que vamos a empezar!
JIT, El nuevo compilador de php 8
JIT, del inglés «just in time«, es básicamente un compilador que permite ejecutar el código en tiempo de ejecución y no antes de la ejecución y que «promete» mejoras importantes en el rendimiento del código, aunque avisan que no esté pensado para trabajar siempre con una petición web.
Con las versiones de php anteriores teníamos al OPCache, que se encargaba de almacenar en una especie de caché, instrucciones de tu codigo para que el tiempo de compilación sólo ocurra cuando sea necesario.
Sin embargo, JIT lo que hace es convertir una porción de ese código en código de máquina para que la Zend VM no sea quien interprete el código si no la CPU directamente.
Aunque aún no hay mucha más información acerca de las mejoras de ese nuevo componente, la verdad es que estudiando lo a simple vista creo que estará mas pensado para la IA que para una web corriente.
Tipos de unión
A priori, podríamos pensar que esto más que una mejora es un engorro, pero la verdad, que yo creo que esto será, con el tiempo, parte fundamental del código y ahora veremos porqué.
Antes en php 7 podiamos dar un tipo a una respuesta de una función o incluso a los parámetros que nos pasaban a una función (sobre todo cuando trabajamos con objetos) y esto en muchas ocasiones nos causaba problemas, por como de restrictivo era.
public function foo( TipoObjeto1 $input) {}
$obj1 = New TipoObjeto1;
$obj2 = New TipoObjeto2;
$output1 = foo($obj1); // Correcto
$output2 = foo($obj2); // Error
BIen, pues esto se acabó con php 8, ahora podremos definir uno o más de un tipos para estos valores directamente en la declaración, pudiendo modificar nuestro código de una forma mas rapida y segura.
public function foo( TipoObjeto1|TipoObjeto2 $input) {}
$obj1 = New TipoObjeto1;
$obj2 = New TipoObjeto2;
$output1 = foo($obj1); // Correcto
$output2 = foo($obj2); // Correcto
Algo parecido nos pasaría con las devoluciones de nuestras funciones, también vamos a poder asignarles diferentes tipos.
public function foo( $input): int|float ;
public function foo2(?Foo $input): int|null;
Operador nullsafe
Seguro que muchas veces en tu código has tenido que hacer algo tan repetitivo como, validar que un valor no esté nulo o que exista (Esto es programación segura básica) teniendo que escribir lineas de código intermedio para realizar estas validaciones.
$country = null;
if ($session !== null) {
$user = $session->user;
if ($user !== null) {
$address = $user->getAddress();
if ($address !== null) {
$country = $address->country;
}
}
}
Pues esto se acabó, ahora, en php 8, vas a poder realizar esta comprobación en una sola línea usando la anotación «?»
$country = $session?->user?->getAddress()?->country;
Lo sé, increíble! hemos eliminado 10 lineas de codigo de una tacada y solo acabamos de empezar.
Argumentos con nombre
Otra de las mejoras que más me encanta es esta, os acordáis cuantas veces habeis tenido una función con mil parámetros, los cuales la mayoría son null or 0, pero habeis tenido que rellenar todos los valores hasta llegar al valor que os interesa?
public function foo($valor1, $valor2 = null, $valor3 = null, $valor4 = null){}
foo("valor1","","valor3");
Pues ahora, basta con ponerle el nombre y el valor en el orden que os interese sin necesidad de rellenar todos los datos intermedios.
public function foo($valor1, ?$valor2 = null, ?$valor3 = null, ?$valor4 = null){}
foo (
valor1: "valor1",
valor3: "valor3", // Spoiler: ahora tambien podemos
//terminar con "coma" una definicion
//como en un array
);
Atributos
Más conocidos como «anotaciones» nos permiten añadir metadatos a las clase, sin tener que analizar el docblocks.
#[ExampleAttribute]
class Foo
{
#[ExampleAttribute]
public const FOO = 'foo';
#[ExampleAttribute]
public $x;
#[ExampleAttribute]
public function foo(#[ExampleAttribute] $bar) { }
}
#[Attribute]
class ExampleAttribute
{
public $value;
public function __construct($value)
{
$this->value = $value;
}
}
Si quereis saber mas sobre este tema os dejo la pagina oficial, donde hablar más en profundidad y dan más ejemplos. Attributes.
Expresión Match
Esta nueva expresión, presume de ser el reemplazo para switch ya que trae con él algunas mejoras, sobretodo en legilibilidad y pone fin al famoso «break» que tan feo se veía en el código.
// #### PHP 7 ####
switch (1) {
case 0:
$result = 'Foo';
break;
case 1:
$result = 'Bar';
break;
case 2:
$result = 'Baz';
break;
defatul:
$result = 'Unnamed';
break;
}
echo $result;
//> Bar
// #### PHP 8 ####
echo match (1) {
0 => 'Foo',
1 => 'Bar',
2 => 'Baz',
default => "Unnamed",
};
//> Bar
Como veis, es un código más limpio, corto y fácil de entender. Pero OJO! al usar esta expresión lo que estamos haciendo es comprar no solo el valor si no el tipo de la variable, es decir si queremos compara un «string» hemos de pasar un «string».
Promoción de propiedades del constructor
Aunque el título pueda parecer algo confuso, la verdad es, que es bastante fácil de entender y es que ahora, podremos especificar una propiedad de clase dentro del mismo constructor ( Esto solo funcionará dentro del constructor ).
Pasaremos de esto:
// #### PHP 7 ####
class Persona
{
public string $name;
public function __construct(
string $name = 'Raul'
) {
$this->name = $name;
}
}
A esto:
// #### PHP 8 ####
class Persona
{
public function __construct(
public string $name = 'Raul',
) {}
}
Como veis, hemos simplificado bastante la creación e inicialización de una propiedad de claro y vuelvo a repetir por si no quedo claro, solo funciona en el construct.
Nuevo tipo Mixed
Tal y como os explique antes en tipos de unión, podíamos devolver una serie de «tipos» de información, bien, pues imaginemos que nos encontramos con alguna de estas situaciones:
- Una función devuelve nada o Null.
- Esperamos uno de varios tipos.
- Esperamos un tipo el cual desconocemos.
Nos volveríamos locos teniendo que poner todos y cada uno de los tipos de retorno. Pues para este caso han creado mixed, el cual nos permite definir una serie de tipos en uno solo.
El valos de mixed solo podran ser los siguientes:
- array
- bool
- callable
- int
- float
- null
- object
- resource
- string
También podremos usar mixed como parámetro o tipo de propiedad, no solo como tipo de retorno.
function bar(): mixed {} //correcto
function bar(): ?mixed {} // Fatal error: Null ya es parte de los tipos incluidos.
Capturas sin captura
Sin duda, otro de los cambios que muchos vamos a agradecer, esto se resumiría en que, ahora, podremos hacer un «catch» de una excepción sin tener que almacenarla en una variable, ya que la gran mayoría de veces ni siquiera se usaba. por esto el codigo quedaria asi:
// #### PHP 7 ####
try {
// Something goes wrong
} catch (MySpecialException $exception) {
Log::error("Something went wrong");
}
// #### PHP 8 ####
try {
// Something goes wrong
} catch (MySpecialException) {
Log::error("Something went wrong");
}
Seguiremos teniendo que definir el tipo del error y en caso de que quieres capturar todas puedes usar, Throwable, como tipo de captura.
Conclusión
Obviamente, estos no son todos los cambios que trae php 8, en realidad la lista es larga y no tendría espacio suficiente para enumerarlas todas, solo he hecho un resumen de las que a mi me han parecido más interesante, porque son las que más uso en mi dia a dia.
En términos generales, php 8, parece un gran avance en cuanto a limpieza de código y facilidad a la hora de escribirlo y entenderlo. Hay muchas cosas que me gustan y que de seguro empezare a usar en cuanto empecemos con esta versión.
Sin embargo, creo que el «avance» real, en cuanto optimización, aún está muy verde. Para los que trabajamos con CMS, o webs, creo que en este aspecto, php 8, no aporta ninguna gran mejora y la verdad que, con lo que cuesta subir de versión, creo que esto ha sido un gran fallo.
Probaremos a fondo el nuevo JIT, a ver que tal se comporta, pero ya os avanzo, que desde mi humilde opinión, creo que se han enfocado más a IA que a web.
Así que, resumiendo, en cuanto a mejora de código les doy buena nota, pero en cuanto a rendimiento, aun sin probar JIT, les doy un suspenso justito.
Podéis ver todos lo cambios en la RFC oficial de php.