Declaraciones de tipos escalares

En PHP 7, las declaraciones de tipos de parámetros de funciones pueden ser escalares. En PHP 5 solo podían ser nombres de clases, interfaces, array o callable (PHP 5.4, es decir, podían ser funciones, incluidas funciones anónimas); ahora también se pueden usar string, int, float y bool.

<?php
// 强制模式
function sumOfInts(int ...$ints)
{
    return array_sum($ints);
}

var_dump(sumOfInts(2, '3', 4.1));

El ejemplo anterior generará la siguiente salida:

int(9)

Es importante tener en cuenta que el problema del modo estricto mencionado anteriormente también aplica aquí: en el modo coercitivo (por defecto, conversión forzada de tipos), los parámetros que no coinciden con lo esperado aún se convierten forzosamente; en el modo estricto, se desencadena un error fatal TypeError.


Declaración de tipo de valor de retorno

PHP 7 añade soporte para declaraciones de tipo de retorno. Similar a las declaraciones de tipos de parámetros, la declaración de tipo de retorno especifica el tipo del valor de retorno de una función. Los tipos disponibles son los mismos que en las declaraciones de parámetros.

<?php

function arraysSum(array ...$arrays): array
{
    return array_map(function(array $array): int {
        return array_sum($array);
    }, $arrays);
}

print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));

El ejemplo anterior generará la siguiente salida:

Array
(
    [0] => 6
    [1] => 15
    [2] => 24
)

Operador de fusión NULL

Debido a que en el uso diario hay muchos casos en los que se usan simultáneamente expresiones ternarias e isset(), el operador de fusión NULL hace que si una variable existe y su valor no es NULL, devuelva su propio valor; de lo contrario, devuelve su segundo operando.

Ejemplo:

<?php
// 如果 $_GET['user'] 不存在返回 'nobody',否则返回 $_GET['user'] 的值
$username = $_GET['user'] ?? 'nobody';
// 类似的三元运算符
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
?>

Operador nave espacial (operador de comparación combinado)

El operador nave espacial se usa para comparar dos expresiones. Devuelve -1, 0 o 1 respectivamente cuando $a es mayor, igual o menor que $b.

Ejemplo:

<?php
// 整型
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1

// 浮点型
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1
 
// 字符串
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1
?>

Definir arrays constantes con define()

Ejemplo:

<?php
define('ANIMALS', [
    'dog',
    'cat',
    'bird'
]);

echo ANIMALS[1]; // 输出 "cat"
?>

Clases anónimas

Ahora se admite instanciar una clase anónima mediante new class. Ejemplo:

<?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 ejemplo anterior generará la siguiente salida:

object(class@anonymous)#2 (0) {
}

Sintaxis de escape de codepoint Unicode

Esto acepta un codepoint Unicode en formato hexadecimal e imprime una cadena codificada en UTF-8 entre comillas dobles o heredoc. Puede aceptar cualquier codepoint válido, y el 0 inicial puede omitirse.

echo "\u{aa}";
echo "\u{0000aa}";
echo "\u{9999}";

El ejemplo anterior generará la siguiente salida:

ª
ª (same as before but with optional leading 0's)
香

Closure::call()

Closure::call() ahora tiene un mejor rendimiento; de manera breve y concisa, permite enlazar temporalmente un método a un objeto a través de una clausura y llamarlo.

<?php
class A {private $x = 1;}

// Pre PHP 7 代码
$getXCB = function() {return $this->x;};
$getX = $getXCB->bindTo(new A, 'A'); // intermediate closure
echo $getX();

// PHP 7+ 代码
$getX = function() {return $this->x;};
echo $getX->call(new A);

El ejemplo anterior generará la siguiente salida:

1
1

Proporcionar filtrado para unserialize()

Esta característica tiene como objetivo proporcionar una forma más segura de desempaquetar datos no confiables. Utiliza una lista blanca para prevenir una posible inyección de código.

<?php

// 转换对象为 __PHP_Incomplete_Class 对象
$data = unserialize($foo, ["allowed_classes" => false]);

// 转换对象为 __PHP_Incomplete_Class 对象,除了 MyClass 和 MyClass2
$data = unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]);

// 默认接受所有类
$data = unserialize($foo, ["allowed_classes" => true]);

IntlChar

La nueva clase IntlChar está diseñada para exponer más funcionalidades de ICU. Esta clase define muchos métodos estáticos para operar con caracteres Unicode de múltiples juegos de caracteres.

<?php
printf('%x', IntlChar::CODEPOINT_MAX);
echo IntlChar::charName('@');
var_dump(IntlChar::ispunct('!'));

El ejemplo anterior generará la siguiente salida:

10ffff
COMMERCIAL AT
bool(true)

Para usar esta clase, instala primero la extensión Intl.


Expectativas

Las expectativas son un método retrocompatible y mejorado de la función assert() anterior. Hacen que habilitar las aserciones en entornos de producción tenga costo cero y proporcionan la capacidad de lanzar excepciones específicas cuando una aserción falla.

<?php
ini_set('assert.exception', 1);

class CustomError extends AssertionError {}

assert(false, new CustomError('Some error message'));
?>

El ejemplo anterior generará la siguiente salida:

Fatal error: Uncaught CustomError: Some error message

Mejoras en use

Las clases, funciones y constantes importadas desde el mismo namespace ahora se pueden importar de una sola vez mediante una única declaración use.

<?php

//  PHP 7 之前版本用法
use some\namespace\ClassA;
use some\namespace\ClassB;
use some\namespace\ClassC as C;

use function some\namespace\fn_a;
use function some\namespace\fn_b;
use function some\namespace\fn_c;

use const some\namespace\ConstA;
use const some\namespace\ConstB;
use const some\namespace\ConstC;

// PHP 7+ 用法
use some\namespace\{ClassA, ClassB, ClassC as C};
use function some\namespace\{fn_a, fn_b, fn_c};
use const some\namespace\{ConstA, ConstB, ConstC};
?>


Mejoras en generadores

Se han mejorado las funciones de Generator, lo que permite implementar muchas características avanzadas.

<?php
<?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 ejemplo anterior generará la siguiente salida:

1
2
3
4

División entera

Se ha añadido la función de división entera intdiv(). Ejemplo de uso:

<?php
var_dump(intdiv(10, 3));
?>

El ejemplo anterior generará la siguiente salida:

int(3)

Para más contenido, puedes consultar:http://www.example.com/php/php7-new-features.html。