Aunque PHP 7 lleva un buen tiempo entre nosotros (desde finales de 2015) muchos desarrolladores de PHP siguen sin aprovechar las magnificas oportunidades y mejoras que se han incorporado al lenguaje en sus últimas versiones. Se han incorporado varios operadores y reglas sintácticas que debemos conocer (y aplicar) para ser mejores programadores. En este artículo queremos ponértelo fácil enumerando las principales novedades de las últimas versiones de PHP: 7, 7.1 y la reciente 7.2.
Mejoras de Rendimiento
La principal mejora de esta nueva versión es el rendimiento. Gracias al proyecto PHPNG (PHP Next Gen) se ha mejorado el núcleo de PHP para conseguir una mejora drástica en todo tipo de aplicaciones. Esta mejora es especialmente notable en CMS como WordPress o Drupal en el que se aumentan las respuestas por segundo hasta el doble que en PHP 5.6. Hay muchos test de velocidad donde poder comprobar como han disminuido tanto los tiempos de respuesta como el numero de peticiones procesadas por segundo como este con symfony o este con wordpress.
Cambios en la sintáxis
Declaraciones de tipo escalar y de tipo de devolución
En PHP 5 se introdujo la posibilidad de declarar el tipo de parámetros de una función cuando era un array, una interfaz o una clase. Ahora se pueden declarar los tipos de parámetros escalares: cadena de caracteres (string), números enteros (int), números decimales (float) y datos booleanos (bool).
1 2 3 4 |
function suma(int $a, int $b) { return $a + $b; } |
Además se introduce la posibilidad de declarar que tipo de dato va a devolver una función o método. Los tipos disponibles son los mismos que para los parámetros.
1 2 3 4 |
function suma(int $a, int $b) : int { return $a + $b; } |
Declaraciones de tipo nullables
Se permiten que las declaraciones de tipo (tanto para parámetros como para devoluciones) sean marcadas como nullables o lo que es lo mismo que el valor pueda ser nulo además del tipo asignado. Para ello usaremos la interrogación ? precediendo al tipo declarado.
1 2 3 4 5 6 |
function suma(int $a, ?int $b) : ?int { if (null == $b) return null; return $a + $b; } |
Funciones void
Se pueden declarar las funciones como void de modo que sepamos de antemano que una función no va a devolver ningún dato (sin return o con return vacío). Para ello usamos el tipo de dato void.
1 2 3 4 |
function no_return($a) : void { return ; } |
Nuevo tipo object
Se puede usar para la declaración de tipos donde se acepta cualquier objeto.
Nuevo seudotipo iterable
Se puede usar para la declaración de tipos donde se aceptan tanto arrays como objetos que implementen la interfaz Traversable.
Use en grupo
Se pueden agrupar las clases, funciones y constantes que se importen desde un mismo namespace en una única sentencia use.
1 2 3 4 5 6 7 |
//En PHP 5 use Example\ClaseA; use Example\ClaseB; use Example\ClaseC as C; //En PHP 7 use Example\{ClaseA, ClaseB, ClaseC as C}; |
Desestructuración de arrays con []
Ahora se puede usar la sintaxis abreviada de array [] para desestructurar arrays como alternativa a list()
1 2 3 4 5 |
//Con list() list($a, $b) = $datos; //Con [] [$a, $b] = $datos; |
Visibilidad de constantes de clase
Se puede especificar la visibilidad de una constante de clase en lugar de que siempre fuesen públicas. Se pueden usar public
, protected
o private
.
Multicaptura de excepciones
Ahora se pueden especificar múltiples excepciones por bloque catch con el carácter |.
1 2 3 4 5 |
try { } catch (FirstException | SecondException $e) { // do something } |
Sobreescribir métodos abstractos
Se permite sobreescribir la definición de un método abstracto cuando una clase abstracta extiende otra clase abstracta.
Nuevas clases y modificaciones en existentes
Clases anónimas
Al igual que ya se hiciese en PHP 5 con las funciones anónimas (Closure) se ha añadido la posibilidad de crear clases anónimas (o más bien objetos anónimos) mediante el uso de new class
.
1 2 3 4 5 6 7 8 9 |
interface Printer { public function print(string $message); } $program->setPrinter(new class implements Printer { public function print(string $message) { echo $message; } }); |
Puedes leer un poco más sobre clases anónimas en php.net.
Expresiones return en generadores
Ahora se permite a los generadores realizar una sentencia return para devolver una expresión final. Este valor se obtendría a través del método getReturn()
que solo es ejecutable una vez se ha finalizado de producir valores.
1 2 3 4 5 6 7 8 9 10 11 12 |
$generator = (function() { yield 1; yield 2; return 3; })(); foreach ($generator as $value) { echo $value; //1, 2 } echo $generator->getReturn(); //3 |
Nuevas funciones y modificaciones en existentes
intdiv()
Para permitir divisiones enteras
random_bytes() y random_int()
Para generar números y caractéres aleatorios criptográficamente seguros y multiplataforma.
Filtros para «unserialize()»
Un problema común al deserializar datos no seguros es una posible inyección de código. Ahora podemos añadir filtros que actúan sobre la clase de objeto a deserializar. De ese modo podemos no permitir clases, permitirlas o incluir una lista de clases aceptadas.
1 2 |
//Solo permitimos ClaseA o ClaseB. De lo contrario recibiremos un objeto __PHP_Incomplete_Class $obj = unserialize($data, ["allowed_classes" => [ClaseA::class, ClaseB::class]]); |
Previsiones
Se ha ampliado la función assert()
para permitir realizar afirmaciones y lanzar excepciones personalizadas cuando dicha afirmación falla. Además no se limita solamente a evular un boolean o string sino que se pueden usar expresiones de todo tipo.
1 |
assert(true == $resultado, new CustomException('Error!')); |
Soporte para claves en list()
Ahora se pueden especificar claves en list() (o en la nueva sintaxis abreviada []).
1 2 3 4 5 6 7 8 9 10 |
$datos = [ ["id" => 1, "nombre" => 'Tom'], ["id" => 2, "nombre" => 'Fred'], ]; // Estilo de list() list("id" => $id1, "nombre" => $nombre1) = $datos[0]; // Estilo de [] ["id" => $id1, "nombre" => $nombre1] = $datos[0]; |
Nuevos operadores
Operador coalescente de null «??» (o de fusión de null)
Se ha incorporado un nuevo operador que nos abrevia una tarea muy común en PHP, establecer un valor a una variable cuando es null
1 2 3 4 5 |
//En PHP 5.X $param = isset($_GET['param']) ? $_GET['param'] : 'defecto'; //En PHP 7.X $param = $_GET['param'] ?? 'defecto'; |
Operador nave espacial «<=>»
Este operador sirve para comparar dos variables ($a y $b) y devolverá -1 si $a es < $b, 0 cuando sean iguales y 1 cuando $a sea mayor que $b.
1 2 3 |
echo 3 <=> 4; // -1 echo 3.4 <=> 3.4; // 0 echo 4 <=> 3; // 1 |
Mejoras al trabajar con caracteres Unicode
Escapar valores hexadecimales
Podemos obtener el código en UTF-8 a partir del valor hexadecimal de un caracter unicode.
1 |
echo "\u{0000aa}; //º |
IntlChar para funcionalidades adicionales
Una nueva clase que nos permite manipular caracteres Unicode usando varias constantes y métodos estáticos como charName()
o ispunct()
Mejoras en seguridad y Criptografia
La libreria Sodium ahora forma parte del nucleo de PHP. Además se han añadido a la API de hashing los password con Argon2. Junto con las nuevas funciones para generar números y caractéres aleatorios (random_bytes() y random_int()) suponen una mejora sustancial en las posibilidades criptográficas.