Новая функциональность
Объявления скалярных типов
Объявления скалярных типов
введена в двух вариантах: принудительный (по умолчанию) и строгий.
Следующие типы могут использоваться для объявления параметров (в обоих вариантах):
строки (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 )
Полную документацию и примеры использования читайте в разделе про объявление возвращаемого типа.
Оператор объединения с null
Был добавлен оператор объединения с null (??
), являющийся
синтаксическим сахаром для достаточно распространенного действия, когда совместно
используются тернарный оператор и функция 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';
?>
Оператор spaceship (космический корабль)
Этот оператор предназначен для сравнения двух выражений. Он возвращает -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
?>
Определение констант массивов с помощью define()
Можно определить константу типа 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
Он принимает шестнадцатеричный код Unicode и записываем его в формате UTF-8 в двойных кавычках или формате heredoc. Любой корректный код будет принят. Ведущие нули по желанию.
echo "\u{aa}";
echo "\u{0000aa}";
echo "\u{9999}";
Результат выполнения данного примера:
ª ª (То же самое, что и первый вариант, но с ведущими нулями) 香
Closure::call()
Closure::call() является более производительным и коротким способом временного связывания области действия объекта с замыканием и его вызовом.
<?php
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);
Результат выполнения данного примера:
1 1
unserialize() с фильтрацией
Этот функционал обеспечивает более высокий уровень безопасности при десериализации объектов с непроверенными данными. Это позволяет предотвратить возможную инъекцию кода, позволяя разработчику использовать белый список классов для десериализации.
<?php
// Преобразование всех объектов в __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
Новый класс 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() теперь является языковой конструкцией, принимающей первым аргументом выражения, а не только строки (string) для оценки или логические значения (bool) для проверки.
<?php
ini_set('assert.exception', 1);
class CustomError extends AssertionError {}
assert(false, new CustomError('Сообщение об ошибке'));
?>
Результат выполнения данного примера:
Fatal error: Uncaught CustomError: Сообщение об ошибке
Подробное описание этого функционала, а также инструкции для его конфигурирования для тестовых и промышленных сред, читайте в секции Ожидания раздела, посвященному assert().
Групповые объявления use
Классы, функции и константы импортируемые из одного и того же 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};
?>
Выражение return в генераторах
Эта функциональность добавлена к генераторам, введенным в 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()
Новая функция 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_array() позволяет писать более чистый код, когда требуется использовать функцию preg_replace_callback(). До PHP 7 при необходимости обработать разные регулярные выражения разными функциями приходилось для каждой такой обработки писать отдельный вызов функции.
Теперь можно использовать одну функцию, передавая в нее ассоциативный массив, ключами которого являются регулярные выражения, а значениями - функции обратного вызова.
Функции CSPRNG
Были добавлены две новые кроссплатформенные функции для генерации криптографически безопасных строк и целых чисел: random_bytes() и random_int().
Теперь функция list() всегда может распаковывать объекты, реализующие ArrayAccess
Ранее функция list() не гарантировала корректную обработку объектов, реализующих ArrayAccess. Теперь это исправлено.
Прочие изменения
-
Добавлена возможность доступа к методам и свойствам класса при клонировании,
то есть
(clone $foo)->bar()
.