Las declaraciones de tipo escalar son de dos tipos: coercitivo (por defecto) y estricto. Ahora se pueden forzar los siguientes tipos para parámetros (tanto coercitiva como estrictamente): cadenas de caracteres (string), números enteros (int), números decimales (float), y booleanos (bool). Estos se añaden a los tipos introducidos en PHP 5: nombres de clases, interfaces, arrays y callables.
<?php
// Modo coercitivo
function sumaDeEnteros(int ...$enteros)
{
return array_sum($enteros);
}
var_dump(sumaDeEnteros(2, '3', 4.1));
El resultado del ejemplo sería:
int(9)
Para habilitar el modo estricto se debe colocar una simple directiva declare al inicio del fichero. Esto siginfica que la rigurosidad de la tipificación de escalares se configura en función de cada fichero. Esta directiva no solamente afecta a las declaraciones de tipo de parámetros, sino también al tipo de devolución de una función (véanse las declaraciones de tipo de devolución), a funciones internas de PHP, y a funciones de extensiones cargadas.
Se puede encontrar la documentación completa y ejemplos de las declaraciones de tipo escalar en la referencia de declaraciones de tipo.
PHP 7 añade soporte para declaraciones de tipo de devolución. Similarmente a las declaraciones de tipo de argumento, las declaraciones de tipo de devolución especifican el tipo del valor que será devuelto por una función. Están disponibles los mismos tipos tanto para las declaraciones de tipo de devolución como para las declaraciones de tipo de argumento.
<?php
function sumarArrays(array ...$arrays): array
{
return array_map(function(array $array): int {
return array_sum($array);
}, $arrays);
}
print_r(sumarArrays([1,2,3], [4,5,6], [7,8,9]));
El resultado del ejemplo sería:
Array ( [0] => 6 [1] => 15 [2] => 24 )
Se puede encontrar la documentación completa y ejemplos de las declaraciones de tipo de devolución en la referencia de las declaraciones de tipo de devolución.
El operador de fusión de null (??) se ha añadido como
aliciente sintáctico para el caso común de la necesidad de utilizar un operador ternario junto
con isset(). Devuelve su primer operando
si existe y no es NULL
; de lo contrario devuelve su segundo operando.
<?php
// Obntener el valor de $_GET['usuario'] y devolver 'nadie'
// si no existe.
$nombre_usuario = $_GET['usuario'] ?? 'nadie';
// Esto equivale a:
$nombre_usuario = isset($_GET['usuario']) ? $_GET['usuario'] : 'nadie';
// La fusión se puede encadenar: esto devolverá el primer
// valor definido de $_GET['usuario'], $_POST['usuario'],
// y 'nadie'.
$nombre_usuario = $_GET['usuario'] ?? $_POST['usuario'] ?? 'nadie';
?>
El operador nave espacial se emplea para comparar dos expresiones. Devuelve -1, 0 o 1 cuando $a es respectivamente menor, igual, o mayor que $b. Las comparaciones se realizan según las reglas de comparación de tipos usuales de PHP.
<?php
// Números enteros
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1
// Numeros decimales
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1
// Cadenas de caracteres
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1
?>
Ahora se pueden definir constantes de array con define(). En PHP 5.6, solamente se podían definir con const.
<?php
define('ANIMALES', [
'perro',
'gato',
'pájaro'
]);
echo ANIMALES[1]; // imprime "gato"
?>
Se ha añadido soporte para clases anónimas mediante new clase. Estas se pueden utilizar en lugar de definiciones de clases completas para objetos desechables:
<?php
interface Logger {
public function log(string $msg);
}
class Application {
private $logger;
public function getLogger(): Logger {
return $this->logger;
}
public function setLogger(Logger $logger) {
$this->logger = $logger;
}
}
$app = new Application;
$app->setLogger(new class implements Logger {
public function log(string $msg) {
echo $msg;
}
});
var_dump($app->getLogger());
?>
El resultado del ejemplo sería:
object(class@anonymous)#2 (0) { }
La documentación completa se puede encontrar en la referencia de clases anónimas.
Esta sintaxis toma un punto de código de Unicode en forma hexadecimal, e imprime ese punto de código en UTF-8 a un string con entrecomillado doble o a un heredoc. Se acepta cualquier punto de código válido, siendo los ceros iniciales opcionales.
echo "\u{aa}";
echo "\u{0000aa}";
echo "\u{9999}";
El resultado del ejemplo sería:
ª ª (lo mismo que antes pero con ceros iniciales opcinales) 香
Closure::call() es una manera más eficiente y abreviada de vincular temporalmente un ámbito de objeto a un cierre e invocarlo.
<?php
class A {private $x = 1;}
// Código anterior a PHP 7
$getX = function() {return $this->x;};
$getXCB = $getX->bindTo(new A, 'A'); // cierre intermedio
echo $getXCB();
// Código de PHP 7+
$getX = function() {return $this->x;};
echo $getX->call(new A);
El resultado del ejemplo sería:
1 1
Esta característica busca el proporcionar una mejor seguridad al deserializar objetos en datos no fiables. Previene de posibles inyecciones de código al capacitar al desarrollador a crear listas blancas de clases que deden ser deserializadas.
<?php
// convertir todos los objetos a un objeto __PHP_Incomplete_Class
$data = unserialize($foo, ["allowed_classes" => false]);
// convertir todos los objetos a un objeto __PHP_Incomplete_Class excepto a los de MiClase y MiClase2
$data = unserialize($foo, ["allowed_classes" => ["MiClase", "MiClase2"]]);
// comportamiento predeterminado (lo mismo que omitir el segundo argumento) que acepta todas las clases
$data = unserialize($foo, ["allowed_classes" => true]);
La nueva clase IntlChar busca exponer funcionalidad adicional de ICU. La clase en sí define varios métodos estáticos y constantes que se pueden emplear para manipular caracteres Unicode.
<?php
printf('%x', IntlChar::CODEPOINT_MAX);
echo IntlChar::charName('@');
var_dump(IntlChar::ispunct('!'));
El resultado del ejemplo sería:
10ffff COMMERCIAL AT bool(true)
Para utilizar esta clase debe estar instalada la extensión Intl.
Las previsiones son una mejora retrocompatible con la antigua función assert(). Con ellas se pueden realizar afirmaciones sin coste en código de producción, proporcionando la capacidad de lanzar excepciones personalizadas cuando la afirmación falla.
Mientras que la API antigua se siguie manteniendo por compatibilidad, assert() ahora es un constructor de lenguaje, permitiendo que el primer parámetro sea una expresión en lugar de solamente un string a evaluar o un valor de tipo boolean a probar.
<?php
ini_set('assert.exception', 1);
class ErrorPersonalizado extends AssertionError {}
assert(false, new ErrorPersonalizado('Un mensaje de error'));
?>
El resultado del ejemplo sería:
Fatal error: Uncaught ErrorPersonalizado: Un mensaje de error
Se pueden encontrar los detalles completos de esta característica, incluyendo cómo configurarla tanto en entornos de desarrollo como de producción, en la sección de previsiones de la referencia de assert().
Las clases, funciones y constantes que se importen desde el mismo namespace ahora pueden ser agrupadas en una única sentencia use.
<?php
// Código anterior a PHP 7
use un\espacioDeNombres\ClaseA;
use un\espacioDeNombres\ClaseB;
use un\espacioDeNombres\ClaseC as C;
use function un\espacioDeNombres\fn_a;
use function un\espacioDeNombres\fn_b;
use function un\espacioDeNombres\fn_c;
use const un\espacioDeNombres\ConstA;
use const un\espacioDeNombres\ConstB;
use const un\espacioDeNombres\ConstC;
// código de PHP 7+
use un\espacioDeNombres\{ClaseA, ClaseB, ClaseC as C};
use function un\espacioDeNombres\{fn_a, fn_b, fn_c};
use const un\espacioDeNombres\{ConstA, ConstB, ConstC};
?>
Esta característica se basa en la funcionalidad de los generadores introducida en PHP 5.5. Habilita a la sentencia return para utilizarla dentro de un generador para que pueda devolver una expresión final (la devolución por referencia no está permitida). Este valor se puede obtener empleando el nuevo método Generator::getReturn(), el cual solamente se puede utilizar una vez que el generador ha finalizado de producir valores.
<?php
$gen = (function() {
yield 1;
yield 2;
return 3;
})();
foreach ($gen as $val) {
echo $val, PHP_EOL;
}
echo $gen->getReturn(), PHP_EOL;
El resultado del ejemplo sería:
1 2 3
La capacidad de devolver explícitamente un valor final desde un generador (quizá desde una forma de computación de corutina) es útil debido a que puede ser específicamente manejado por el código del cliente que ejecuta el generador. Esto es mucho más simple que forzar al código del cliente a comprobar primero si el valor final se ha generado y luego, si es asi, manejar dicho valor específicamente.
Los generadores ahora pueden delegar a otro generador, objeto Traversable o array de forma automática, sin la necesidad de escribir «clichés» en el generador más externo con la construcción yield from.
<?php
function gen()
{
yield 1;
yield 2;
yield from gen2();
}
function gen2()
{
yield 3;
yield 4;
}
foreach (gen() as $val)
{
echo $val, PHP_EOL;
}
?>
El resultado del ejemplo sería:
1 2 3 4
La nueva función intdiv() realiza una división entera de sus operandos y la devuelve.
<?php
var_dump(intdiv(10, 3));
?>
El resultado del ejemplo sería:
int(3)
session_start() ahora acepta un array de opciones que sobrescriben las directivas de configuración de sesiones establecidas normalmente en php.ini.
Estas opciones también se han ampliado para admitir session.lazy_write, la cual está activada de forma predeterminada y causa que PHP solamente sobrescriba cualquier fichero de sesión si los datos de sesión han cambiado, y read_and_close, la cual es una opción que se puede pasar solo a session_start() para indicar que los datos de sesión deberían ser leídos y luego la sesión debería ser cerrada inmediatamente sin cambios.
Por ejemplo, para establecer session.cache_limiter a private e inmediatamente cerrar la sesión después de leerla:
<?php
session_start([
'cache_limiter' => 'private',
'read_and_close' => true,
]);
?>
Con la nueva función preg_replace_callback_array(), el código escrito es más claro al emplear la función preg_replace_callback(). Antes de PHP 7, las retrollamadas que necesitaban ser ejecutadas por cada expresión regular requerían que la función de retrollamda fuera contaminada con muchas ramificaciones.
Ahora, las retrollamadas se pueden registrar para cada expresión regular usando un array asociativo, donde la clave es una expresión regular y el valor es una retrollamada.
Se han añadido dos nuevas funciones para generar números enteros y cadenas de caractéres criptográficamente seguros de una forma multiplataforma: random_bytes() y random_int().
Anteriormente, no se garantizaba que list() operase correctamente con objetos que implementasen ArrayAccess. Esto ha sido arreglado.