PHP 7.0: Головні нововведення
PHP 7.0 завершує епоху «п’ятірок»: з’являються скалярні оголошення типів (типово — coercive, а strict_types=1 увімкують свідомо), типи, що повертаються, оператори ?? та <=>, анонімні класи, Closure::call(), конструкція yield from і явний return у генераторі з читанням через Generator::getReturn(), функція intdiv(), random_bytes() / random_int() для криптостійких випадковостей, фільтрований unserialize() і preg_replace_callback_array().
Під капотом багато колишніх fatal перетворюються на Error, TypeError, ParseError у спільній ієрархії Throwable. Якщо глобальний обробник очікує лише Exception, перший TypeError може зірвати обробку запиту — варто оновити сигнатури та стратегію логування.
Зміст
- Скалярні типи й
strict_types - Типи повернення
- Оператор
?? - Оператор
<=> - Анонімні класи
Closure::call()- Генератори
intdiv(), CSPRNG,unserialize- Груповий
use - Практичні рецепти
- Зворотна несумісність
- Що прибрали з поставки
- Deprecated
- Інші нотатки
Скалярні типи й strict_types
До параметрів додаються string, int, float, bool поряд із класами, array, callable. Без declare(strict_types=1); PHP лишається «пом’якшеним»: рядок "10" може стати int. Увімкнули суворість — невідповідність одразу TypeError.
declare(strict_types=1);
function increment(int $x): int {
return $x + 1;
}
Типи повернення
Оголошений тип результату перевіряється під час виконання; void і пов’язані правила з’являються в 7.1.
Оператор ??
$name = $_GET['name'] ?? 'guest';
Не породжує notice для відсутніх індексів — зручніше за каскади isset.
Оператор <=>
Повертає -1 / 0 / 1 — ідеально для usort і власних компараторів.
usort($rows, function ($a, $b) {
return $a['score'] <=> $b['score'];
});
Анонімні класи
$logger = new class implements LoggerInterface {
public function log($level, $message, array $context = []) { /* … */ }
};
Closure::call()
$getter = function () { return $this->value; };
$getter->call($object);
Генератори
yield from делегує іншому iterable; return $x; після завершення доступний через getReturn().
intdiv(), CSPRNG, unserialize
intdiv: цілочисельне ділення,/0→ArithmeticError.random_bytes/random_int: криптостійкі значення між ОС.unserialize(..., ['allowed_classes' => [...]]): білий список класів.
Груповий use
use Foo\Bar\{Baz, Qux};
Практичні рецепти
$limit = (int) ($_GET['limit'] ?? 25);
usort($items, function ($a, $b) {
return strcmp($a['id'], $b['id']);
});
Зворотна несумісність
Повна картина — migration70 incompatible. Короткий чеклист:
Помилки
Throwable; багато fatal →Error.set_exception_handler(Exception $e)небезпечний — потрібенThrowableабо без типу.
Синтаксис і змінні
- Вирази на кшталт
$$foo['bar']['baz']читаються зліва направо; для старої семантики PHP 5 потрібні{}з мануала. list(): порядок присвоєння за оголошенням змінних; порожнійlist()заборонено; рядок черезlist()не розпаковується.
Масиви й foreach
- Інша поведінка внутрішнього покажчика і копії при ітерації за значенням.
- Зайві дужки біля аргумента-by-ref більше не «прибирають» попередження.
Рядки й числа
- Шістнадцяткові рядки
"0x…"не підхоплюються як числа автоматично. - Складні
"${...}"у подвійних лапках — перегляньте шаблони.
Текст UTF-8
substr/strlen— у байтах; для користувацького тексту додавайтеmb_*.
Що прибрали з поставки
mysql_*, ereg_*, низка SAPI — migration70 removed. Заміна: mysqli/PDO, preg_*.
Deprecated
Конструктори як ім’я класу, статичні виклики не-static методів, ручна сіль у password_hash, ldap_sort, capture_session_meta — migration70 deprecated.
Інші нотатки
assert і zend.assertions, зміни JSON, зникнення split() → preg_split/explode.
Підсумок
5.x → 7.0 — окремий проєкт: прибрати mysql/ereg, додати catch (Throwable $e), прогнати регресію list()/foreach. Далі мінори 7.1+ крокують спокійніше.