PHP 7.0: Основни нововъведения

PHP 7.0 е поколенска промяна след 5.x: скаларни декларации на типове (по подразбиране coercive, а strict_types=1 включва строг режим), типове за връщане, операторите за сливане с null (??) и тристранното сравнение (<=>), анонимни класове, Closure::call(), връщане на стойност от генератор и yield from, intdiv(), random_bytes() / random_int(), филтриран unserialize() и preg_replace_callback_array().

Под капака много бивши fatal стават Error в йерархията Throwable. Ако глобалният обработчик приема само Exception, първият TypeError може да счупи цялата заявка — обновете сигнатурите и логиката за грешки.

Съдържание


Скаларни типове и 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;
}

Връщани типове

Функциите и методите могат да декларират тип на резултата; при несъответствие се хвърля TypeError. void и свързаните правила идват в 7.1; на 7.0 фокусът е върху връщане на стойност.

Оператор ??

$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 и връщане

  • yield from делегира итерация на друг генератор или iterable.
  • return $final; вътре в генератор излага стойността чрез Generator::getReturn() след приключване.

intdiv(), CSPRNG, опции за unserialize

  • intdiv($a, $b) — целочислено деление; при /0ArithmeticError.
  • random_bytes() / random_int() — криптографски устойчиви случайни стойности между ОС (за тайни предпочитайте пред mt_rand()).
  • unserialize($data, ['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; много fatalError, TypeError, ParseError.
  • set_exception_handler: ако параметърът е типизиран като Exception, при Error може да последва нов fatal — използвайте Throwable или без тип на PHP 7+.

Парсер и променливи

  • Косвен достъп до променливи/свойства/методи се оценява строго отляво надясно — изрази като $$foo['bar']['baz'] изискват явни {}, за да запазят смисъла от PHP 5.
  • list(): редът на присвояване следва дефиницията на променливите; празен list() е невалиден; низ не се разопакова с list() (ползвайте str_split() и т.н.).

Масиви, foreach, функции

  • Редът на елементи, създадени чрез присвояване по референция, се различава от PHP 5.
  • foreach вече не мести вътрешния указател на масива; foreach по стойност работи върху копие; итерацията по референция следва добавянията по-предсказуемо.
  • Излишни скоби вече не потискат предупреждението „само променливи трябва да се подават по референция“.

Низове и цели числа

  • Шестнадесетични низове ("0xFF") не се третират автоматично като числа в числов контекст.
  • Сложни форми с $ в двойни кавички и ${} — прегледайте генерирани шаблони.

Unicode и изход

  • substr() и подобни остават байтови — за UTF-8 текст комбинирайте с mb_*.

Много точки по разширения (mysql, ereg и др.) са под премахнато по-долу.

Премахнати разширения и SAPI

PHP 7 маха класически разширения и SAPI от ерата 4/5 — mysql, ereg*, mssql, sybase_ct, стари SAPI и др. — вижте migration70 removed. mcrypt още присъства в 7.0, но по-късно се обявява за deprecated. Заменете mysql_* с mysqli или PDO, а ereg_* — с preg_*.

Deprecated

Конструктори в стил PHP 4 с името на класа, статични извиквания на не-static методи, опция за собствена сол в password_hash(), ldap_sort(), capture_session_meta в SSL контекст и още — migration70 deprecated.

Други бележки за миграция

  • assert() поддържа expectations API с zend.assertions в INI — низовите assertions остават капан при миграция (по-късно deprecated в 7.x).
  • Прегледайте премахнати INI директиви, променено поведение при грешки в json_decode/json_encode и премахването на split() (ползвайте preg_split() / explode()).

Обобщение

Надграждането 5.x → 7.0 е проект, не една корекция: статичен анализ, махане на mysql/ereg, catch (Throwable $e) около входните точки на приложението и проверка на list()/foreach. След стабилизиране на 7.0 минорните 7.1+ са по-инкрементални — nullable типове, после предупреждения за count() в 7.2, после heredoc и JSON изключения в 7.3.