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

PHP 7.3 в клона 7.x е издание за полиране и безопасност: по-удобен ежедневен синтаксис (гъвкав heredoc/nowdoc, завършващи запетаи в извиквания, референции в list() / деструктуриране []), малки, но полезни помощници (array_key_first(), array_key_last(), is_countable(), hrtime()) и платформени обновления (JSON_THROW_ON_ERROR / JsonException, PASSWORD_ARGON2ID, PCRE2, сериозни промени в mbstring). При миграция отделно проверете парсирането на низове (тяло heredoc срещу затварящ етикет, PCRE класове), семантиката на референциите (достъп през масив/свойство, низови ключове към ArrayAccess) и разширенията (дробни секунди в MySQL, подразбирания на IMAP, имена на бисквитки от 7.3.23).

Съдържание


Гъвкав Heredoc и Nowdoc

Затварящият етикет може да бъде с отстъп; същият отстъп се премахва от всички редове в тялото. SQL, HTML и дълги текстове стават по-четими в отместен код.

Миграция: ако вътре в низа се среща същият токен като затварящия етикет, PHP може да прекрати низа преждевременно — използвайте дълги уникални етикети.

$query = <<<SQL
    SELECT id, name
    FROM users
    WHERE active = 1
    SQL;

Завършващи запетаи в извиквания на функции и методи

След последния аргумент в извикване е позволена запетая — удобно за многоредови diff и генерирани списъци:

$this->logger->info(
    'User saved',
    [
        'id' => $user->id,
        'ip' => $request->ip(),
    ],
);

Става дума за извиквания, не за декларация на параметри в други версии.

Присвояване по референция в list() и []

Поддържа се деструктуриране по референция:

[&$head, $middle, &$tail] = $parts;
list(&$a, $b) = $pair;

Използвайте съзнателно, когато променяте обща структура.

instanceof с литерали

Отляво може да е литерал — резултатът винаги е false. Предназначено е предимно за еднаквост и статичен анализ.

CompileError

Нов базов клас CompileError, от който наследява ParseError. Инструменти с token_get_all(..., TOKEN_PARSE) могат да получават изключения вместо някои fatals.

Нови и обновени помощници в ядрото

  • array_key_first() / array_key_last()
  • is_countable() — масиви и Countable
  • hrtime() — монотонно време с висока резолюция
  • net_get_interfaces() — зависи от ОС

JSON: JSON_THROW_ON_ERROR и JsonException

$data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);

При комбинация с JSON_PARTIAL_OUTPUT_ON_ERROR приоритет има последният флаг.

Хеширане на пароли: Argon2id

PASSWORD_ARGON2ID за password_hash() при подходяща сборка с libargon2.

Забележими промени в разширенията и stdlib

  • PCRE2; preg_quote() екранира и #
  • mbstring: Unicode 11, много дълги низове, case-folding, именувани групи в mb_ereg_*
  • LDAP controls, MySQLi/PDO с дробни секунди, FPM и getallheaders()
  • setcookie / session с масив от опции и SameSite
  • IPv6 в stream_socket_get_name() в квадратни скоби
  • SPL autoload: изключение спира следващите автoload-ери
  • IMAP: rsh/ssh по подразбиране изключени

Практически рецепти

Преди count()

if (is_countable($rows)) {
    $n = count($rows);
}

Първи и последен ключ

$firstKey = array_key_first($map);
$lastKey = array_key_last($map);

Строг JSON

try {
    $payload = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
    // обработка
}

Интервал с висока резолюция

$t0 = hrtime(true);
$elapsedNs = hrtime(true) - $t0;

Обратно несъвместими промени (миграционни бележки)

Ядро

  • Гъвкав heredoc: етикет в тялото → синтактична грешка или промяна на смисъл.
  • continue в switch: предупреждение; в PHP това е като break.
  • ArrayAccess с низов литерал "123": няма неявно привеждане към int — offsetGet("123"), не offsetGet(123).
  • Статични свойства: не може да се „раздели“ наследяването чрез присвояване по референция.
  • Референции от [] / ->: незабавно се разгръщат.
  • ...$traversable: нецелочислени ключове — без unpacking в извикване.
  • EH_THROW изключения: не попълват error_get_last().
  • TypeError: в текста int / bool, не integer / boolean.
  • compact(): неопределени имена → notice.
  • BMP MIME в getimagesize()image/bmp.
  • Бисквитки (от PHP 7.3.23): имената не се URL-декодират.

BCMath

  • Предупрежденията минават през стандартния error handler.
  • bcmul() / bcpow() спазват scale по-строго.

IMAP

  • rsh/ssh изключени по подразбиране; с ненадеждни имена на пощенски кутии е рисковано да ги включите.

Multibyte regex

  • Именувани групи променят $matches и mb_ereg_replace().

MySQLi и PDO MySQL

  • Дробни секунди могат да счупят тестове за точен низ на време.

Reflection

  • Изходът ползва int / bool.

SimpleXML

  • Аритметиката с текстови възли избира int/float по-подходящо.

Други

  • BeOS премахнат; ext_skel пренаписан.
  • IPv6 формат с скоби в stream_socket_get_name().

Deprecated (поправете рано)

  • Регистронезависими define() и ползване с различен регистър от дефиницията.
  • Функция assert() в namespace — не я декларирайте.
  • Не-низова игла в strpos семейството — явно (string) или chr().
  • fgetss(), gzgetss(), SplFileObject::fgetss(), филтър string.strip_tags.
  • FILTER_FLAG_SCHEME_REQUIRED / FILTER_FLAG_HOST_REQUIRED при FILTER_VALIDATE_URL.
  • image2wbmp() (GD).
  • Normalizer::NONE при ICU ≥ 56.
  • Недокументирани алиаси mbereg_*mb_ereg_*.
  • INI pdo_odbc.db2_instance_name формално deprecated.

Пълен списък: migration73 deprecated.

Други промени и експлоатация

  • Syslog INI: syslog.facility, syslog.filter, syslog.ident; от 7.3.8 филтър raw възстановява по-агресивното старо логване.
  • GC: подобрен цикличен събирач — профили на дългоживеещи процеси могат да се променят.
  • var_export() за stdClass чрез (object) array (...).
  • FTP: подразбиран режим binary.
  • FILTER_VALIDATE_FLOAT: опция thousand за разделители на хилядите.
  • OpenSSL: min_proto_version / max_proto_version за потоци.
  • PDO SQLite: само четене чрез PDO::SQLITE_ATTR_OPEN_FLAGS.
  • XML: връщаната стойност на handler за външни entity се уважава при libxml.
  • cURL: изисква се libcurl ≥ 7.15.5.
  • OPcache: премахнат opcache.inherited_hack.
  • ODBC: премахнати Birdstep / ODBCRouter.

Обобщение

Прегледайте continue+switch, compact, ArrayAccess, heredoc етикети и ...$iterator. След тестове на regex и дата/време планирайте 7.4 — там са typed properties и по-голяма стъпка; ранното чистене на deprecations от 7.3 улеснява пътя.