PHP 7.2 — Что нового?
PHP 7.2 вышел 30 ноября 2017. Изменения в PHP 7.2 не стали столь существенными по сравнению с версией 7.1. В данной статье мы рассмотрим обновления, улучшения производительности, а также устаревшие функции, которые будут удалены в следующей версии.
Оптимизация
В Opcache добавлена глобальная оптимизация на основе анализа потока данных с использованием SSA (Static single assignment form): Sparse Conditional Constant Propagation (SCCP), удаление мертвого кода (Dead Code Elimination — DCE) и удаление неиспользуемых локальных переменных.
Оптимизирована работа встроенной функции in_array()
с помощью поиска хеша в перевернутом массиве.
Нововведения
Добавлена возможность загружать расширения по имени (RFC)
Раньше extension=
и zend_extension=
в файле php.ini содержали пути до файла расширения.
Имя файла зависело от платформы.
Теперь вы можете писать:
1 2 |
<span class="hljs-attr">extension</span>=bz2 <span class="hljs-attr">zend_extension</span>=xdebug |
И нужные расширения будут подгружены в зависимости от ОС.
Этот механизм будет работать при установке extension и zend_extension в ini-файле, а также как аргумент для функции dl()
.
Но абсолютные пути по-прежнему необходимо будет указывать при флаге -z
в CLI-режиме, а также при указании абсолютного пути.
Следующий пример работать не будет:
extension=/path/to/extensions/bz2
Добавлена возможность перегружать абстрактные функции (RFC)
Теперь вы сможете перегрузить абстрактные функции точно так же, как и обычные функции:
1 2 3 |
<span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">A</span> </span>{ <span class="hljs-keyword">abstract</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bar</span><span class="hljs-params">(stdClass $x)</span></span>; } <span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">B</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">A</span> </span>{ <span class="hljs-keyword">abstract</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bar</span><span class="hljs-params">($x)</span>: <span class="hljs-title">stdClass</span></span>; } <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">C</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">B</span> </span>{ <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bar</span><span class="hljs-params">($x)</span>: <span class="hljs-title">stdClass</span></span>{} } |
До PHP 7.2 выдавалась ошибка.
Запрещено number_format() возвращать -0 (RFC)
Вызов number_format(-0.00)
возвращал string(1) “0”
, однако number_format(-0.01)
возвращал string(2) “-0”
. Сейчас же будет возвращен 0 без знака.
Добавлена возможность конвертировать нумерованные ключи при приведении типов object/array (RFC)
Запрещено передавать null в качестве параметра для get_class() (RFC)
Вызов Count с параметром, который нельзя посчитать (RFC)
Теперь вызов count()
с параметром, который является скалярным, null или объектом, который не реализовал интерфейс Countable, будет выдавать Warning
.
Возможность расширения типа параметра (RFC)
Одно из самых горячо обсуждаемых изменений — возможность не указывать тип параметра в наследнике. Таким образом наследник сможет принять параметр любого типа.
Добавлена возможность указывать запятую в конце группированных неймспейсов (RFC)
1 2 3 |
$array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>,]; // Раньше это работало только для массивов <span class="hljs-keyword">use</span> <span class="hljs-title">Foo</span>\<span class="hljs-title">Bar</span>\{ <span class="hljs-title">Foo</span>, <span class="hljs-title">Bar</span>, <span class="hljs-title">Baz</span>, }; // Теперь и для группировки неймспейсов |
Реализовано семейство функций socket_getaddrinfo (RFC)
Теперь из PHP будет доступна информация из getaddrinfo()
, реализованная на C. Это недостающая функция для текущей библиотеки сокетов. При работе с различными сетями было бы полезно разрешить libc
рассказать нам, какие методы подключения/прослушивания будут наиболее подходящими с учетом набора подсказок.
Были утверждены четыре функции:
1 2 3 4 |
socket_addrinfo_lookup(string node[, mixed service, <span class="hljs-keyword">array</span> hints]) : <span class="hljs-keyword">array</span> socket_addrinfo_connect(resource $addrinfo) : resource socket_addrinfo_bind(resource $addrinfo) : resource socket_addrinfo_explain(resource $addrinfo) : <span class="hljs-keyword">array</span> |
Улучшены TLS-константы (RFC)
Теперь:
tls://
имеет дефолтное значениеTLSv1.0 + TLSv1.1 + TLSv1.2
ssl://
это алиас кtls://
- константа
STREAM_CRYPTO_METHOD_TLS_*
имеет дефолтное значениеTLSv1.0 + TLSv1.1 + TLSv1.2
вместоTLSv1.0
- константа
STREAM_CRYPTO_METHOD_SSLv23_CLIENT
считается устаревшей и позже будет удалена.
Object typehint (RFC)
LDAP EXOP (RFC)
Добавлены функции для использования расширенных операций LDAP в php-ldap.
В ядро PHP добавлена Libsodium (RFC)
Libsodium — современная криптографическая библиотека, которая предлагает аутентифицированное шифрование, высокоскоростную криптографию с эллиптическими кривыми и многое другое. В отличие от других криптографических стандартов (которые являются набором криптографических примитивов, например, WebCrypto), libsodium включает в себя тщательно подобранные алгоритмы, реализованные экспертами по безопасности. Это поможет избежать уязвимостей в сторонних каналах.
Добавлен алгоритм Argon2 в хешировании пароля (RFC)
Argon2 — это современный простой алгоритм, направленный на высокую скорость заполнения памяти и эффективное использование нескольких вычислительных блоков.
HashContext as Object (RFC)
Добавлены отладчики PDO Prepared statements (RFC) и PDO Prepared statements v2 (RFC)
Расширенные типы строк для PDO (RFC)
Добавлены опции JSON_INVALID_UTF8_IGNORE и JSON_INVALID_UTF8_SUBSTITUTE (Request)
Для функций json_encode
/ json_decode
добавлены новые опции JSON_INVALID_UTF8_IGNORE
и JSON_INVALID_UTF8_SUBSTITUTE
для игнорирования или замены некорректных последовательностей байтов UTF-8.
Удалено из PHP 7.2
Следующий функционал объявлен устаревшим и был удален.
Удалены строки без кавычек (bare word) (RFC)
Строки без кавычек теперь вызывают E_WARNING
.
К примеру:
1 2 |
$foo = flase; <span class="hljs-comment">// Опечатка, но раньше вызывалась ошибка E_NOTICE, которую часто отключали. </span> |
Перенос mcrypt в PECL
Расширение mcrypt, объявленное устаревшим в PHP 7.1, было перемещено в PECL.
Объявлено устаревшим в PHP 7.2 (RFC)
Следующий функционал объявлен устаревшим и больше не рекомендуется к использованию.
Этот функционал будет удален в версии 8.0.
__autoload
Функция __autoload
была заменена на spl_autoload_register
ещё в версии 5.1.
Основным преимуществом spl_autoload_register
является возможность использовать несколько автозагрузчиков.
png2wbmp() и jpeg2wbmp()
Png2wbmp()
и jpeg2wbmp()
— единственные функции, изменяющие формат изображений, которые можно вызвать напрямую, доступные в ext / gd
, что делает их довольно обособленными, поскольку libgd не предлагает таких функций. Кроме того, WBMP
был изобретен для поддержки WAP
, который в настоящее время устарел. Теперь будет выбрасываться Deprecation notice
.
$php_errormsg
Переменная $php_errormsg
создается в локальной области при возникновении нефатальной ошибки, если параметр track_errors
включен (отключен по умолчанию), и ошибка не перехватывалась никаким обработчиком ошибок.
Помимо того, что поведение зависело от настроек ini-файла, оно также было магическим. Функция error_get_last
обеспечивает более чистый способ получения последней ошибки. С PHP 7 доступна функция error_clear_last
, таким образом, охватываются все возможные варианты использования $php_errormsg
без манипуляции с областями видимости.
create_function()
create_function()
— это тонкая оболочка вокруг конструкции языка eval()
, позволяющая создавать функцию со сгенерированным именем, списком аргументов и телом в виде строковых аргументов. До введения замыканий в PHP 5.3 она обеспечивала способ создания чего-то похожего на лямбда-функции.
Из-за характера работы create_function()
, помимо потенциального источника проблем безопасности, имеет очень плохие характеристики производительности и использования памяти. Использование реальных замыканий во всех отношениях предпочтительнее.
mbstring.func_overload
Параметр mbstring.func_overload
в ini-файле позволяет заменить определенное подмножество строковых функций на аналоги с расширением mbstring. Например, strlen()
больше не будет возвращать длину строки в байтах, вместо этого она вернет длину в символах в соответствии с текущей выбранной внутренней кодировкой.
Это означает, что код с использованием mbstring.func_overload
не совместим кодом, написанным в предположении, что основные операции со строками работают нормально. Некоторые библиотеки прямо запрещают func_overload
(например, Symfony), другие библиотеки перестают работать. Код, который хочет поддерживать func_overload, должен условно переключаться между обычными строковыми функциями и функциями mbstring с 8-битным кодированием (обычно только библиотеки для криптографии пытаются это сделать).
Теперь будет выбрасываться Deprecation notice
если mbstring.func_overload
содержит ненулевое значение.
(unset) cast
Каст (unset)
превращает значение в null. Это означает, что (unset) expr
— просто выражение, которое всегда возвращает null и не имеет других побочных эффектов.
Помимо бесполезности, это поведение только путает, так как многие люди разумно предполагают, что (unset) $a
будет вести себя аналогично unset($a)
, а на самом деле этого не происходит.
Функция parse_str() без второго аргумента
Функция parse_str()
разбирает строку URL и присваивает значения переменным в текущем контексте (или заносит в массив, если задан параметр result).
Использовать эту функцию без параметра result крайне не рекомендовалось, потому что динамическое создание переменных в области видимости функции ведет ровно к тем же проблемам, что и register_globals. Теперь выбрасывается Deprecation notice
, если параметр result не передается.
Функция gmp_random()
Функция gmp_random()
генерирует случайное число. Число будет в диапазоне нуля до произведения числа limiter на количество бит в лимбе (limb). Если число limiter отрицательное, будет возвращен отрицательный результат.
Лимб — внутренний GMP-механизм. Технически это часть числа, помещающаяся в одно машинное слово. Количество бит в нем может различаться в разных системах. В основном это либо 16, либо 32, но это не гарантируется. Так происходит, потому что реализация GMP/MPIR не доступна пользователю. Таким образом, использование этой функции требует угадывания размера Лимба и может зависеть от платформы.
Чтобы исправить это, в PHP 5.6 добавили функции gmp_random_bits()
и gmp_random_range()
, которые позволяют точно контролировать используемый диапазон случайных чисел. Эти функции всегда должны быть предпочтительнее, чем gmp_random()
.
Функция each()
Функция each()
может использоваться для итерации по массиву, подобно foreach, однако ф
ункция
each
уступает foreach
практически во всём, среди прочего она в 10 раз медленнее.
Функция assert() со строковым аргументом
Функция assert()
имеет два режима работы: если передано что-то, кроме строки, она будет проверять, что значение является истиной. Если была передана строка, она будет запущена через eval()
, и assert будет проверять истинность результата eval()
.
Причиной такого поведения является то, что до PHP 7 это было единственным способом предотвратить вычисление выражения. Начиная с PHP 7 опция zend.assertions
в ini-файле может использоваться, чтобы избежать вычисления выражений. Таким образом, больше нет необходимости поддерживать неявное вычисление строковых аргументов.
Использование assert($value)
для проверки истинности значения открывает уязвимость удаленного выполнения кода, если существует вероятность того, что $value
будет строкой.
Теперь выбрасывается Deprecation notice
, если assert()
используется со строковым аргументом.
$errcontext аргумент в error handler
Обработчикам ошибок, заданных с помощью set_error_handler()
, передается в качестве последнего аргумента $errcontext
. Этот аргумент представляет собой массив, содержащий все локальные переменные в месте, где была сгенерирована ошибка.
Эта функция трудна для оптимизации, поскольку $errcontext
может использоваться для изменения всех ссылок и объектов в текущей области видимости. Эта функциональность практически не используется. Если вы хотите проверить переменные состояния в месте ошибки, вы должны использовать debugger.
Обратите внимание, что контекст ошибки содержит только локальные переменные. Ошибки backtrace, включая $this
и аргументы функции, останутся доступны через debug_backtrace()
.
Этот функционал будет отмечен в документации как устаревший.
Константа INTL_IDNA_VARIANT_2003
Объявлены устаревшими приведение типов (binary) и b»» литералы (RFC)
Приведение типа (binary)
и поддержка префикса b
были добавлены в PHP 5.2.1
для совместимости с PHP 6
, однако эта версия так и не появилась, и неизвестно, будут ли когда-нибудь ещё попытки реализовать двоичные строки. Тем не менее, они все еще принимаются языковым сканером, хотя и игнорируются.
Попробовать новую версию онлайн:
https://3v4l.org/