Вышел PHP 7.1 — сделаем обзор RFC, вошедших в свежий релиз.
Привет мир!
Вы слушаете «Пятиминутку PHP», выпуск номер 25 — подкаст о новостях из мира PHP, интересных постах в блогах и современных подходах к разработке.
Рад всех поздравить с выходом PHP версии 7.1.0. Давайте сделаем краткий обзор RFC, вошедших в этот релиз.
Напомню, что список всех RFC по уже вышедшим версиям и планирующиеся на будущее можно найти по адресу wiki.php.net/rfc
-
Session ID without hashing
ID сессии издревна генерировался с помощью специальной хэш-функции. Самое главное в этом процессе — сделать ID сессии непредсказуемым, чтобы посторонний человек не смог его подобрать. Теперь используется функцияphp_random_bytes()
обёрнутая в вызовbin_to_readable()
. -
Asynchronous Signal Handling
В предыдуших версиях PHP сигналы от операционной системы обрабатывались синхронным способом. Была возможность запустить и асинхронную обработку, но это просаживало производительность. Благодаря улучшениями виртуальной машины PHP 7.1 стало возможным обрабатывать сигналы асинхронно без дополнительного overhead’а. -
Fix inconsistent behavior of $this variable
Зналили вы, что была возможность переопределить переменную$this
тысячью разными способами, например, сделать unset или использовать в качестве переменной для значения вforeach
? Теперь все способы испортить$this
будут вызывать Fatal Error или Exception Error. -
Replace «Missing argument» warning with «Too few arguments» exception
Называние говорит само за себя: если мы забыли передать требуемые аргументы в функцию, то теперь получим Exception (раньше был Warning). -
Nullable Types
А что если функция может принимать в качестве аргумента какой-то определённый тип илиnull
? Мы всегда писали в определении функции имя аргумента= null
. В PHP 7.1 добавлен новый синтаксис: знак вопроса перед типом. Например, пишем:function foo(?string $x)
— аргумент$x
может принимать значение типаstring
илиnull
. Обращу внимание, что новая запись не эквивалентна старой. Если используем новый синтаксис со знаком вопроса, то аргумент от этого не становится не обязательным. Он должен быть явно передан в функцию, даже если мы хотим передатьnull
, иначе получим Exception «too few arguments» из предыдущего RFC. Также этот синтаксис со знаком вопроса позволяет отметить и тип возвращаемого значения, как nullable. -
Square bracket syntax for array destructuring assignment
Альтернативный синаксис для конструкцииlist()
о котором я подробно рассказывал в выпуске №21 — теперь вместоlist
можно использовать квадратные скобки. -
Warn about invalid strings in arithmetic
При использовании арифметических операций со строками, которые не являются числами в чистом виде, PHP не выдавал никаких сообщений, а просто конвертировал строки в числа. Например, если сложить «10 яблок» + «5 апельсинов» получим результат 15. В PHP 7.1 такая операция покажет нам предупреждение уровня E_NOTICE или E_WARNING (результат при этом всё равно будет 15). -
Allow specifying keys in list()
На этот этот RFC я опять же делал обзор в выпуске №21 — конструкциюlist
теперь можно использовать не только для разбора пронумерованных массивов, но и для ассоциативных массивов, явно указывая ключи, которые мы хотим извлечь. -
Iterable
У нас есть типarray
и интерфейсTraversable
по которым можно итерироваться с помощьюforeach
. Но у нас не было возможности определить тип аргумента функции или тип возвращаемого значения, какarray
илиTraversable
одновременно, т.е. когда мы заранее не знаем, какой именно тип будет использован. Новый псевдо-типIterable
покрывает и массивы иTraversable
объекты. Вы спросите, что за псевдо-тип такой и как его использовать. Вот вам ближайшая аналогия: вспомните псевдо-типcallable
. -
Generalize support of negative string offsets
Появилась возможность использовать отрицательное смещение при работе со строками. Например, можно получить второй символ с конца строки, указав для строковой переменной$foo[-2]
. Поддержка отрицательного смещения также появляется и в функцияхstrpos
,mb_strpos
,file_get_contents
и многих других (полный список читайте в RFC по ссылке). -
Closure from callable function
Хотите создавать Closure (анонимные функции с захватом контекста) из переменных типаcallable
просто, в одну строку и быстро в рантайме без рефлексии? Теперь у класса Closure появился публичный статический методClosure::fromCallable()
. В описании к RFC есть пара удачных примеров, посмотрите, чтобы понять зачем это может пригодиться. -
Deprecate mb_ereg_replace eval option
Опцияe
в функцияхmb_ereg_replace
иmb_eregi_replace
объявлена устаревшей (depricated). Эта опция позволяла выполнитьeval
, что без должного внимания могло привести к проблемам с безопасностью. -
Deprecate (and remove) Mcrypt
В PHP 7.1 вызов всехmcrypt_*
функций будет показывать предупреждение E_DEPRECATED, а в одной из будущих версий (7.2 или 8.0) планируется вынести эти функции из ядра в отдельное PECL расширение. -
OpenSSL AEAD support
В функцииopenssl_decrypt
иopenssl_encrypt
добавлены параметры для поддержи так называемого режима AEAD (Authenticated Encrypt with Associated Data) — те кто в теме, поймут. Я не в теме. -
Void Return Type
Новый тип void для описания возвращаемых результатов. Если мы ненароком вернём из такой функции некое значение (включаяnull
), то получим Fatal Error. При этом сделать простоreturn
(без какого либо значения) для раннего выхода из функции можно — это и будетvoid
. Обратите внимание, что в качестве типа аргументов функцииvoid
не применим. -
Class constant visibility modifiers
Теперь перед объявлением констант можно указывать модификаторы доступаprivate
,protected
иpublic
. Если не указать ничего, то константа считаетсяpublic
, как и в предыдущих версиях. -
Octal Overflow Protection
В PHP можно указать значение одного байта используя восьмеричную систему, написав в двойных кавычках обратный слэш (\) и восьмеричное число из трёх цифр. Наример,"\101"
— это число 65 в десятичной системе. Однако, чтобы уложиться ровно в 1 байт, максимальная восмеричная форма — это"\377"
. Предыдущие версии PHP не выводили ошибок при переполнении, т.е. при указании числа большего чем 377. В PHP 7.1 будет выведен Warning. -
RNG fixes and changes
Несколько улучшений в функциях работы со случайными числами, которые, внимание, повлекли за собой breaking change: при заданном значении seed, функцииmt_rand
,rand
,array_rand
,shuffle
,str_shuffle
иcrypt
теперь вернут иное значение, чем в предыдуших версиях. Это может стать причиной трудно понимаемых багов при переходе на 7.1. В моих проектах, в частности, есть один фрагмент, который полагается на заданный seed перед вызовомarray_rand
. -
Add HTTP/2 Server Push support to ext/curl
В PHP 7.0 в расширении curl появилась поддержка нескольких фич из HTTP/2. В PHP 7.1 добавляется ещё одна очень классная функциональность: поддержка HTTP/2 Server Push. Это актуально, если вы используете PHP приложение в качестве клиента и подключаетесь к внешнему ресурсу по HTTP/2. -
TimeZone::getWindowsID
В классIntlTimeZone
добавлено два статических метода:getWindowsID()
иgetIDForWindowsID()
. Пример: если вызватьIntlTimeZone::getWindowsID("America/Los_Angeles")
то получим"Pacific Standard Time"
. И наоборот, если вызватьIntlTimeZone::getIDForWindowsID("Pacific TimeZone")
, то получим"America/Los_Angeles"
. Эти методы появились благодаря обновлению библиотеки ICU. -
Multi catch
В блоке catch при работе с исключениями можно поймать несколько исключений одновременно, перечислив их типы через вертикальную черту. -
Forbid dynamic calls to scope introspection functions
В PHP есть ряд функций, которые меняют или читают переменные из текущей области видимости:extract()
,compact()
,get_defined_vars()
,parse_str()
,mb_parse_str()
,assert()
со строковым аргументом,func_get_args()
,func_get_arg()
иfunc_num_args()
. Теперь эти функции запрещено вызывать динамически, т.е. с помощьюcall_user_func()
илиarray_map()
и подобными способами. Во-первых, динамический вызов этих функций давал различный результат в разных версиях PHP и в целом такой код был сложен для понимания и зачастую имел неожиданный результат. Во-вторых, динамический вызов этих функций сложно оптимизировать с точки зрения виртуальной машины PHP и это сильно ударяло по производительности. Ещё раз отмечу, что сами функции никуда не исчезают, просто их нужно вызывать явно! -
Add curl_multi_errno(), curl_share_errno() and curl_share_strerror()
Расширение curl создаёт ресурс одного из трёх типов: так называемый handle из функцииcurl_init()
, Multi Handle из функцииcurl_multi_init()
и Share Handel из функцииcurl_share_init()
. Чтобы получить ошибку соединения у нас была функция curl_errno(), которая применима для первого типа Handle. Но не было аналогичных функций для Multi Handle и Share Handle. Теперь они появились:curl_multi_errno()
иcurl_share_errno()
— возвращают код ошибки;curl_multi_strerror()
иcurl_share_strerror()
— возвращаю описание ошибки. -
Throw Error in Extensions
В PHP 7.0 мы смогли перехватывать стандартные ошибки PHP как исключение Error, но это ещё не работало в расширениях. В PHP 7.1 подтянулись и расширения, такие какDate
,DOM
,mbstring
и другие. -
More precise float value handling
Улучшения в точности обработкиfloat
значений, что сразу будет заметно при работе с функциямиserialize()
,json_encode()
. -
Additional Context in pcntl_signal Handler
Добавлен второй аргумент в виде массива кcallback
функции при использованииpcntl_signal
— теперь наш обработчик сигналов получит вторым аргументом дополнительную информацию, контекст. -
Add session_create_id()
Добавлиена функцияsession_create_id()
, про котороую лучше прочитать в документации — тонкости работы с сессиями такие тонкие… -
Add session_gc()
Добавлена функцияsession_gc()
для принудительного запуска сборщика мусора старых сессий. За подробностями зачем это нужно и в каких случаях применять опять же рекомендую почитать документацию.
Это обновление не такое громкое, как 7.0. Нет информации о серьёзном увеличении производительности, зато подчищены некоторые старые хвосты, добавлено немного синтаксического сахара, в целом годный инкрементальный релиз. Обновляемся по плану!
https://www.google.ru/?gws_rd=ssl#newwindow=1&q=curl+how+to+pronounce
We pronounce curl and cURL with an initial k sound: [kurl].