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 - Връщани типове
- Оператор
?? - Оператор
<=> - Анонимни класове
Closure::call()- Генератори:
yield fromи връщане intdiv(), CSPRNG, опции заunserialize- Групов
use - Практически рецепти
- Обратна несъвместимост (обобщено)
- Премахнати разширения и SAPI
- 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;
}
Връщани типове
Функциите и методите могат да декларират тип на резултата; при несъответствие се хвърля 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)— целочислено деление; при/0→ArithmeticError.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; много fatal →Error,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.