Новые функции в PHP 7: что изменилось и как использовать

Раздел: PHP -> Версии PHP

Новые возможности PHP 7

Как добавить строгую типизацию для скалярных параметров и возвращаемых значений?

PHP 7 вводит возможность указывать типы для параметров (int, float, string, bool) и для возвращаемых значений функций. Это повышает надёжность кода и выявляет ошибки на этапе разработки. Например, функция может принимать только целые числа и возвращать строку.

<?php
function sum(int $a, int $b): string {
    return 'Сумма: ' . ($a + $b);
}
echo sum(3, 5); // "Сумма: 8"
?>

язык php 4 (php 4)

Почему при передаче дробного числа возникает ошибка?

Если не включена строгая типизация (declare(strict_types=0) по умолчанию), PHP пытается преобразовать переданное значение. При declare(strict_types=1) передача float в int вызовет TypeError. Решение: убедиться, что передаваемые значения соответствуют объявленному типу, или использовать приведение ((int)).

Как использовать оператор объединения с null (??) и тернарный оператор?

Оператор ?? (null coalescing) возвращает первый операнд, если он не равен null, иначе второй. Это заменяет конструкции isset() + тернарный оператор.

<?php
$username = $_GET['user'] ?? 'гость';
echo $username;
?>

язык php 5 (php 5)

Результат: значение 'user' или 'гость'

Php 7 функции (новые функции php 7)

Чем отличается ?? от ?: при работе с несуществующими ключами массива?

Тернарный оператор ?: проверяет на истинность (false, 0, '' и т.д.), а ?? только на null и несуществующий ключ без предупреждения. Ошибка: использование ?: может вызвать E_NOTICE, если ключ не определён. Решение: предпочитать ?? для проверки существования.

Как работает оператор космического корабля (spaceship) <=> ?

Оператор <=> сравнивает два выражения и возвращает -1, 0 или 1, если первый операнд меньше, равен или больше второго. Используется в пользовательских сортировках для упрощения кода.

<?php
function compare($a, $b) {
    return $a <=> $b;
}
$arr = [3, 1, 4, 2];
usort($arr, 'compare');
print_r($arr);
?>

Php v 7 (php версия 7)

Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 )

Php 8 function (функции php 8)

Почему при сравнении строк и чисел результат может быть неожиданным?

Оператор <=> сначала приводит типы к одному (если не включена строгая типизация). Например, '5' <=> 5 даст 0. Для строкового сравнения без приведения используйте strcmp. Решение: явно приводить типы перед сравнением.

Как объявить анонимный класс?

PHP 7 позволяет создавать анонимные классы для одноразового использования, например, для реализации интерфейса без создания отдельного файла.

<?php
$logger = new class {
    public function log(string $msg) {
        echo "[LOG] $msg\n";
    }
};
$logger->log('Тест');
?>

Можно ли наследовать анонимный класс?

Да, через extends внутри объявления. Однако это может усложнить отладку. Ошибка: попытка сериализовать анонимный класс вызовет исключение. Решение: избегать сериализации таких объектов.

- Php 8.4 windows (php 8.4 на windows)
- Php 8 json (php 8: изменения в работе с json)
- Php 7 3 (php версии 7.3)

Расширенные примеры с новыми функциями PHP 7

Пример
<?php
declare(strict_types=1);

// Комбинация nullable возвращаемых типов и void
function findUser(int $id): ?array {
    $users = [1 => ['name' => 'Alice']];
    return $users[$id] ?? null;
}

$user = findUser(1);
var_dump($user);
// array(1) { ["name"]=> string(5) "Alice" }

$user = findUser(99);
var_dump($user);
// NULL

// Использование iterable в цикле
function processElements(iterable $items): void {
    foreach ($items as $item) {
        echo $item . "\n";
    }
}

processElements([1, 2, 3]);
// 1 2 3

// Анонимный класс с реализацией интерфейса
interface Logger {
    public function write(string $message): void;
}

$fileLogger = new class('app.log') extends SplFileObject implements Logger {
    public function __construct(string $file) {
        parent::__construct($file, 'a');
    }
    public function write(string $message): void {
        $this->fwrite(date('Y-m-d H:i:s') . ' ' . $message . "\n");
    }
};

$fileLogger->write('Старт приложения');

// Оператор ?-> (nullsafe) в PHP 8, но предшественник в PHP 7 - isset с ?:
// В PHP 7 нет nullsafe, поэтому пример для контекста:
$obj = null;
$value = $obj?->property ?? 'default'; // не работает в PHP 7
?>
Результат выполнения: см. комментарии в коде.

Как использовать поддержку Group Use Declarations (PHP 7)?

Пример
<?php
// Вместо:
use Foo\Bar\Baz;
use Foo\Bar\Qux;
// Можно:
use Foo\Bar\{Baz, Qux};

echo Baz::class;
echo Qux::class;
?>

Как работает генерация исключений при несоответствии типов?

Пример
<?php
declare(strict_types=1);

function multiply(int $a, int $b): int {
    return $a * $b;
}

try {
    echo multiply(2, '3');
} catch (\TypeError $e) {
    echo 'Ошибка: ' . $e->getMessage();
}
// Ошибка: Argument 2 passed to multiply() must be of the type int, string given
?>
Результат: перехвачено TypeError.

Новые функции PHP 7 - comments

En
Php 7 функции (php)