PHP 7.0+


7.0+

== Тип переменного числа аргументов ==


// Принудительный режим
function sumOfInts(int ...$ints)
{
    return array_sum($ints);
}

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


== Тип возврата функции ==

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]));


== ?? - значение или null ==

// Извлекаем значение $_GET['user'], а если оно не задано,
// то возвращаем 'nobody'
$username = $_GET['user'] ?? 'nobody';
// Это идентично следующему коду:
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

// Данный оператор можно использовать в цепочке.
// В этом примере мы сперва проверяем, задан ли $_GET['user'], если нет,
// то проверяем $_POST['user'], и если он тоже не задан, то присваеваем 'nobody'.
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';


== Операция сравнения чисел/строк ==

// Целые числа
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1

== Объявление констант-массивов ==

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


== Анонимные классы при вызове функции ==

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());


== Короткое связывание замыканий через call ==

class A {private $x = 1;}

// До PHP 7
$getX = function() {return $this->x;};
$getXCB = $getX->bindTo(new A, 'A'); // промежуточное замыкание
echo $getXCB();

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


== Расширение ожиданий assert ==

ini_set('assert.exception', 1);

class CustomError extends AssertionError {}

assert(false, new CustomError('Сообщение об ошибке'));


== Групповой импорт из именных пространств ==

use somenamespace{ClassA, ClassB, ClassC as C};
use function somenamespace{fn_a, fn_b, fn_c};
use const somenamespace{ConstA, ConstB, ConstC};


== Получение последнего значение генератора ==

$gen = (function() {
    yield 1;
    yield 2;
    return 3;
})();

foreach ($gen as $val) {
    echo $val, PHP_EOL;
}

echo $gen->getReturn(), PHP_EOL;


== Связывание генераторов в цепочки ==

function gen()
{
    yield 1;
    yield 2;
    yield from gen2();
}

function gen2()
{
    yield 3;
    yield 4;
}

foreach (gen() as $val)
{
    echo $val, PHP_EOL;
}

== Анонимное клонирование ==

(clone $foo)->bar()