Los cambios en el lenguaje de PHP 5.5

15 de junio de 2013

Al margen de la nueva API para codificar contraseñas, de la nueva extensión OPcache y de los nuevos generadores PHP, la versión 5.5 de PHP incluye varias novedades en el propio lenguaje. A continuación se explican las cinco novedades más importantes.

Accediendo a elementos de arrays y caracteres de cadenas

PHP 5.5 permite acceder de forma directa a los elementos de un array y a los caracteres de una cadena de texto cuando se definen como literales (lo que se conoce en inglés como "array & string dereferencing"):

$amigo = ["amigo1", "amigo2", "amigo3", "amigo4"][1];
// $amigo = "amigo2"

$inicial = "Palabra"[0];
// $inicial = 'P'

La propiedad ::class

A partir de PHP 5.5, todas las clases definen una propiedad estática llamada ::class y que devuelve el nombre cualificado completo de la clase. En otras palabras, ::class devuelve el nombre de la clase junto con su namespace completo.

namespace Symfony\Component\HttpFoundation;

class Request { ... }

$nombreCompleto = Request::class;
// $nombreCompleto = "Symfony\Component\HttpFoundation\Request"

La palabra reservada finally

Los bloques try-catch ahora pueden definir un nuevo bloque de código bajo la nueva palabra clave finally. El código encerrado dentro de finally se ejecuta siempre, independientemente de las excepciones que se produzcan.

try {
    $total = 0;
    $numProductos = 0;
    $precioMedio = $total / $numProductos;

    // ...
} catch (Exception $e) {
    echo "Excepción: ".$e->getMessage();
} finally {
    echo "Este código se ejecuta siempre.";
}

Si no se produce ninguna excepción, la ejecución de la aplicación es la siguiente:

  1. Se ejecuta el código encerrado por el bloque try.
  2. Se ejecuta el código encerrado por el bloque finally.
  3. Se continúa ejecutando el resto de la aplicación.

Si se produce alguna excepción, la aplicación se ejecuta de la siguiente manera:

  1. Se intenta ejecutar el código del bloque try, pero se produce una excepción.
  2. Se ejecuta el código encerrado por el bloque catch definido para la excepción que se ha producido.
  3. Se ejecuta el código definido por el bloque finally.
  4. Se continúa ejecutando el resto de la aplicación o se detiene por completo en función del código ejecutado en el bloque catch anterior.

Los bloques finally son muy útiles por ejemplo para asegurar que la aplicación cierra correctamente los descriptores de archivos (función fclose()) y para cerrar conexiones con las bases de datos (función mysqli_close()):

$db = mysqli_connect();

try {
    // hacer consultas a la base de datos
} finally {
    mysqli_close($db);
}

La estructura foreach y la función list()

La estructura de control foreach ahora puede extraer los elementos individuales cuando se recorren arrays de arrays.

Antes de PHP 5.5, esta era la única forma de acceder a los elementos individuales de los arrays interiores:

$productos = [
    ["Nombre 1", "Precio 1", "Descripción 1"],
    ["Nombre 2", "Precio 3", "Descripción 2"],
    ["Nombre 3", "Precio 3", "Descripción 3"]
];

foreach ($productos as $producto) {
    $nombre      = $producto[0];
    $precio      = $producto[1];
    $descripcion = $producto[2];

    // ...
}

A partir de la versión 5.5, puedes utilizar el siguiente código más conciso y fácil de entender:

$productos = [
    ["Nombre 1", "Precio 1", "Descripción 1"],
    ["Nombre 2", "Precio 3", "Descripción 2"],
    ["Nombre 3", "Precio 3", "Descripción 3"]
];

foreach ($productos as list($nombre, $precio, $descripcion)) {
    // ...
}

Si el número de variables de list() es inferior al número de elementos del array, se ignoran los elementos sobrantes del array. Si el número de variables de list() es mayor que el número de elementos de cada array, se muestra un error de tipo Notice: Undefined offset.

La función empty() admite expresiones

La función empty() ahora admite como argumento cualquier tipo de expresión, no sólo variables.

if (empty(function () { return false; })) {
    echo "El valor pasado es vacío.";
}

Recuerda que la función empty() es en realidad un atajo de !isset($var) || $var == false. Por lo tanto, los siguientes valores se consideran vacíos: una cadena de texto vacía, un array sin elementos, una variable declarada pero sin valor, null, false, 0, "0" y 0.0.

Con este cambio, el código de las aplicaciones se puede simplificar al realizar comprobaciones sobre el valor devuelto por las funciones:

// antes de PHP 5.5 había que hacer así las comprobaciones
if (empty($producto = findProducto($productoId))) {
    error('No se ha encontrado el producto');
}

// con PHP 5.5 el código anterior se simplifica
if (empty(findProducto($productoId))) {
    error('No se ha encontrado el producto');
}