Декларация скалярных типов введена в двух вариантах: принуждающая (по умолчанию) и строгая. Следующие типы могут использоваться для декларации параметров (в обоих вариантах): строки (string), целые (int), рациональные числа (float) и логические значения (bool). Они дополняют аргументы других типов, введенных в PHP 5: имена классов, интерфейсов, array и callable.
<?php
// Принуждающий режим
function sumOfInts(int ...$ints)
{
return array_sum($ints);
}
var_dump(sumOfInts(2, '3', 4.1));
Результат выполнения данного примера:
int(9)
Для установки строгого режима, в самом начале файла необходимо поместить одну директиву declare. Это означает, что строгость декларации работает на уровне файла и не затрагивает весь остальной код. Эта директива затрагивает не только декларацию параметров, но и возвращаемые значения функций (смотри декларация возвращаемого типа), встроенные функции PHP и функции загруженных расширений.
Подробную документацию и примеры использования читайте в разделе декларация типов.
В PHP 7 добавлена поддержка декларация возвращаемого типа. Аналогично как и декларация типов аргументов, декларация типа возвращаемого значения указывает, значение какого типа должна вернуть функция. Для декларации типа возвращаемого значения доступны все те же типы, что и для декларации типов аргументов.
<?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]));
Результат выполнения данного примера:
Array ( [0] => 6 [1] => 15 [2] => 24 )
Подробную документацию и примеры использования читайте в разделе декларация возвращаемого типа.
Был добавлен оператор объединения с nul (??), являющийся
синтаксическим сахаром для достаточно распространенного действия, когда совместно
используются тернарный оператор и функция isset(). Он возвращает
первый операнд, если он задан и не равен NULL
, а в обратном случае возвращает второй
операнд.
<?php
// Извлекаем значение $_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';
?>
Этот оператор предназначен для сравнения двух выражений. Он возвращает -1, 0 или 1 если $a, соответственно, меньше, равно или больше чем $b. Сравнение производится в соответствии со правилами сравнения типов PHP.
<?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
?>
Можно задать константу типа array с помощью функции define(). В PHP 5.6, такие константы можно было задавать только с помощью const.
<?php
define('ANIMALS', [
'dog',
'cat',
'bird'
]);
echo ANIMALS[1]; // выводит "cat"
?>
Была добавлена поддержка анонимных классов с помощью new class. Их можно использовать тогда, когда нужен одноразовый класс и создавать полноценный класс, а потом его объект не имеет смысла:
<?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());
?>
Результат выполнения данного примера:
object(class@anonymous)#2 (0) { }
Подробную документацию и примеры использования читайте в разделе анонимные классы.
Берем шестнадцатеричный код Unicode и записываем его в формате UTF-8 в двойных кавычках или формате heredoc. Любой корректный код будет принят. Лидирующие нули по желанию.
echo "\u{aa}";
echo "\u{0000aa}";
echo "\u{9999}";
Результат выполнения данного примера:
ª ª (То же самое, что и первый вариант, но с лидирующими нулями) 香
Closure::call() является более производительным и коротким способом временного связывания области действия объекта с замыканием и его вызовом.
<?php
class A {private $x = 1;}
// До PHP 7
$getXCB = function() {return $this->x;};
$getX = $getXCB->bindTo(new A, 'A'); // промежуточное замыкание
echo $getX();
// PHP 7+
$getX = function() {return $this->x;};
echo $getX->call(new A);
Результат выполнения данного примера:
1 1
Этот функционал обеспечивает более высокий уровень безопасности при десериализации объектов с непроверенными данными. Это позволяет предотвратить возможную инъекцию кода, позволяя разработчику использовать белый список классов для десериализации.
<?php
// Преобразование всех объектов в into __PHP_Incomplete_Class
$data = unserialize($foo, ["allowed_classes" => false]);
// Преобразование всех объектов кроме MyClass и MyClass2 в __PHP_Incomplete_Class
$data = unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]]);
// Поведение по умолчанию принимает все классы (можно просто не задавать второй аргумент)
$data = unserialize($foo, ["allowed_classes" => true]);
Новый класс IntlChar добавляет новую функциональность в ICU. Класс определяет несколько статических методов и констант для манипулирования символами Unicode.
<?php
printf('%x', IntlChar::CODEPOINT_MAX);
echo IntlChar::charName('@');
var_dump(IntlChar::ispunct('!'));
Результат выполнения данного примера:
10ffff COMMERCIAL AT bool(true)
Для использования это класса необходимо установить расширение Intl.
Ожидания являются улучшенной, обратно совместимой версией старой функции assert(). Они позволяют делать предположения с нулевой стоимостью в промышленном коде и предоставляют возвожность выбрасывать пользовательские исключения в случае провала ожидания.
Вместе тем, что старое API поддерживается, assert() теперь является языковой конструкцией, принимающей первым аргументом выражения, а не только строки для оценки или логические значения для проверки.
<?php
ini_set('assert.exception', 1);
class CustomError extends AssertionError {}
assert(false, new CustomError('Some error message'));
?>
Результат выполнения данного примера:
Fatal error: Uncaught CustomError: Some error message
Подробное описание этого функционала, а так же инструкции для его конфигурирования для тестовых и промышленных сред, читайте в секции Ожидания раздела посвященному assert().
Классы, функции и константы импортируемые из одного и того же namespace, теперь можно группировать в одном операторе 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};
?>
Эта функциональность добавлена к генераторам, введенным в PHP 5.5. Она позволяет использовать оператор return в генераторах в качестве финального возвращаемого значение (возврат по ссылке не допустим). Это значение можно извлечь с помощью нового метода Generator::getReturn(), которые можно использовать только после того, как генератор вернул все сгенерированные значение.
<?php
$gen = (function() {
yield 1;
yield 2;
return 3;
})();
foreach ($gen as $val) {
echo $val, PHP_EOL;
}
echo $gen->getReturn(), PHP_EOL;
Результат выполнения данного примера:
1 2 3
Возможность явно получать финальное значение генератора является очень полезной, так как позволяет клиентскому коду, использующему генератор, получать и обработать самое последнее значение генератора, после которого точно ничего больше не будет. Это сильно проще, чем вынуждать разработчика проверять, последнее ли значение вернулось и как-то по особенному его обрабатывать.
Теперь генератор может автоматически делегировать другому генератору, объекту класса Traversable или массиву без необходимости писать в нем дополнительную обработку полученных значений. Достигается это с помощью конструкции 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;
}
?>
Результат выполнения данного примера:
1 2 3 4
Новая функция intdiv() производит целочисленное деление операндов и возвращает его результат.
<?php
var_dump(intdiv(10, 3));
?>
Результат выполнения данного примера:
int(3)
Теперь session_start() принимает массив опций, которые переопределят конфигурационные директивы сессии установленные в php.ini.
Также, опции были расширены включенной по умолчанию опцией session.lazy_write, которая говорит PHP о том, что файл сессии надо перезаписывать, только если изменились даные сессии, и и опцией read_and_close, которую можно задать только через session_start() для того, чтобы PHP закрывал сессию сразу же как прочитает ее данные и не вносил в нее каких либо изменений.
К примеру, для задания session.cache_limiter равным private и немедленному закрытию сессии после чтения ее данных:
<?php
session_start([
'cache_limiter' => 'private',
'read_and_close' => true,
]);
?>
Новая функция preg_replace_callback_array() позволяет писать более чистый код, когда требуется использовать функцию preg_replace_callback(). До PHP 7, при необходимости обработать разные регулярные выражения разными функциями, приходилось для каждой такой обработки писать отдельный вызов функции.
Теперь же можно использовать одну функцию, передавая в нее ассоциативный массив,\ключами которого являются регулярные выражения, а значениями - функции обратного вызова.
Были добавлены две новые кроссплатформенные функции для генерации криптографически безопасных строк и целых чисел: random_bytes() и random_int().
Ранее, функция list() не гарантировала корректную обработку объектов реализующих ArrayAccess. Теперь это исправлено..