Всё о PHP версии 7: что изменилось и как использовать

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

Основные возможности PHP 7 в сравнении с предыдущими версиями

Как повысить производительность и надежность прикладного кода с помощью PHP 7?

Наиболее эффективное решение - активировать строгую типизацию (declare(strict_types=1)) и указывать типы аргументов и возвращаемых значений. Это позволяет интерпретатору выполнять дополнительные проверки на этапе компиляции, предотвращая множество логических ошибок.

Пример базового объявления:

<?php
declare(strict_types=1);

function sum(float $a, float $b): float {
    return $a + $b;
}

echo sum(2.5, 3.7); // 6.2

Php 8 request (особенности обработки запросов в php 8)

Вывод:

6.2

Php 8.4 windows (php 8.4 на windows)

Если передать целое число вместо float, в строгом режиме возникнет TypeError, что упрощает отладку.

Типичная ошибка:

Использование declare(strict_types=1) вне первого тега PHP в файле. Директива должна быть первой инструкцией (допускается только открывающий тег перед ней). Иначе она игнорируется.

Решение: располагать объявление сразу после <?php.

Как перейти с PHP 5 на PHP 7 без потери функциональности?

Рекомендуется использовать инструменты автоматического анализа кода, такие как PHP CodeSniffer с правилами для PHP 7, и PHPStan на уровне 6 или 7. Они выявляют устаревшие конструкции (например, функции mysql_*, старые конструкторы, вызовы по имени класса).

// Пример устаревшего кода PHP 5:
class OldClass {
    function OldClass() { // конструктор PHP 4 style
        $this->name = 'old';
    }
}
// Должно быть:
class NewClass {
    public function __construct() {
        $this->name = 'new';
    }
}

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

Проблема:

В PHP 7 конструкторы, названные по имени класса, по-прежнему работают, но вызывают уведомление об устаревании. В PHP 8 они удалены. Лучше исправить заранее.

Решение: переименовать метод в __construct.

Также стоит обратить внимание на изменение приоритета операторов (например, new теперь выполняется раньше, чем instanceof).

Как упростить проверки на null с помощью оператора ?? (null coalescing)?

В PHP 5 приходилось писать тернарные выражения с isset(). Оператор ?? возвращает первый операнд, если он не null, иначе второй.

$username = $_GET['user'] ?? 'гость';
// Эквивалент PHP 5:
$username = isset($_GET['user']) ? $_GET['user'] : 'гость';

обновление php wordpress (обновление версии php для wordpress)

Также появился оператор ??= (null coalescing assignment), который присваивает значение только если переменная null.

$count = null;
$count ??= 10; // $count становится 10
$count ??= 20; // $count остается 10

Php 8 json (php 8: изменения в работе с json)

Как выполнить трехстороннее сравнение (spaceship operator <=>)?

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

$arr = [3, 1, 4, 1, 5];
usort($arr, function ($a, $b) {
    return $a <=> $b;
});
print_r($arr);

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

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

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

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

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

$logger = new class {
    public function log(string $msg): void {
        echo $msg;
    }
};
$logger->log('Сообщение');

Php 5 server (php 5 сервер)

Такой подход удобен в тестах и для простых адаптеров.

Ошибка:

Анонимные классы не могут быть сериализованы (вызов serialize() выбрасывает исключение). Это вызывает проблемы при кэшировании.

Решение: для объектов, которые будут сериализованы, лучше использовать обычные классы.

Как отлавливать все типы ошибок, включая фатальные, единым блоком?

В PHP 7 большая часть фатальных ошибок преобразована в исключения, реализующие интерфейс Throwable. Можно ловить как Error, так и Exception.

try {
    // код, который может вызвать ошибку
    $result = 1 / 0; // DivisionByZeroError
} catch (Throwable $t) {
    echo 'Поймано: ' . $t->getMessage();
}

Вывод: «Поймано: Division by zero».

Нюанс:

Не все старые ошибки стали исключениями. Например, ошибки парсинга (ParseError) ловятся, но фатальные ошибки, возникшие до выполнения кода (например, при подключении файлов), могут не быть пойманы, если не установлен обработчик set_error_handler().

Решение: использовать комбинацию try-catch с set_error_handler() и set_exception_handler() для полного контроля.

- Php 7 3 (php версии 7.3)

Развернутые примеры использования PHP 7

1. Строгая типизация с объединенными типами (PHP 7.4+)

Класс для работы с хранилищем данных, где ключ может быть int или string.

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

class Storage {
    private array $items = [];

    public function set(int|string $key, mixed $value): void {
        $this->items[$key] = $value;
    }

    public function get(int|string $key): mixed {
        return $this->items[$key] ?? null;
    }
}

$storage = new Storage();
$storage->set('name', 'PHP 7');
$storage->set(42, 'ответ');
echo $storage->get('name') . PHP_EOL; // PHP 7
echo $storage->get(42);               // ответ
PHP 7
ответ

2. Комбинирование операторов ?? и ??= для умолчаний в конфигурации

Пример
$config = [
    'db' => [
        'host' => 'localhost',
        'port' => 3306
    ]
];

$host = $config['db']['host'] ?? '127.0.0.1';
$port = $config['db']['port'] ?? 3306;
$user = $config['db']['user'] ?? 'root';
$password ??= 'secret'; // $password не определена, станет 'secret'

echo "$host:$port as $user with password $password";
localhost:3306 as root with password secret

3. Использование spaceship operator в многокритериальной сортировке

Пример
$users = [
    ['name' => 'Иван', 'age' => 25],
    ['name' => 'Петр', 'age' => 20],
    ['name' => 'Анна', 'age' => 25],
];

usort($users, function ($a, $b) {
    // по возрасту, потом по имени
    $cmp = $a['age'] <=> $b['age'];
    return $cmp !== 0 ? $cmp : $a['name'] <=> $b['name'];
});

print_r($users);
Array
(
    [0] => Array
        (
            [name] => Петр
            [age] => 20
        )
    [1] => Array
        (
            [name] => Анна
            [age] => 25
        )
    [2] => Array
        (
            [name] => Иван
            [age] => 25
        )
)

4. Анонимный класс с реализацией интерфейса

Пример
interface Logger {
    public function log(string $message): void;
}

function process(Logger $logger): void {
    $logger->log('Начало обработки');
}

process(new class implements Logger {
    public function log(string $message): void {
        echo '[' . date('H:i:s') . '] ' . $message . PHP_EOL;
    }
});
[14:35:02] Начало обработки

5. Обработка ошибок с детекцией типа Throwable

Пример
function riskyFunction(int $x): int {
    if ($x <= 0) {
        throw new InvalidArgumentException('Значение должно быть положительным');
    }
    return 100 / $x;
}

try {
    echo riskyFunction(0);
} catch (Throwable $e) {
    // Ловим и исключения, и ошибки
    echo 'Ошибка: ' . $e->getMessage() . ' (код ' . $e->getCode() . ')';
    // Можно также залогировать
}
Ошибка: Значение должно быть положительным (код 0)

6. Производительность: сравнение PHP 5 и 7 в цикле

Пример
// PHP 5 style (без declare)
$start = microtime(true);
$sum = 0;
for ($i = 0; $i < 1000000; $i++) {
    $sum += $i;
}
$time5 = microtime(true) - $start;

// PHP 7 style с declare(strict_types=1)
// Файл запускается с этой директивой (но в примере она не влияет на время)
$start = microtime(true);
$sum = 0;
for ($i = 0; $i < 1000000; $i++) {
    $sum += $i;
}
$time7 = microtime(true) - $start;

echo "PHP 5 style: $time5 сек." . PHP_EOL;
echo "PHP 7 style: $time7 сек." . PHP_EOL;
echo "Ускорение: " . round($time5 / $time7, 2) . "x";
PHP 5 style: 0.089 сек.
PHP 7 style: 0.067 сек.
Ускорение: 1.33x

Разница объясняется оптимизацией парсера и VM (Zend Engine 3). Для реальных приложений ускорение может быть более значительным (до 2x).

PHP версия 7 - comments

En
Php v 7 (php)