- PVSM.RU - https://www.pvsm.ru -
list()
image2wbmp()
объявлена устаревшейFILTER_FLAG_SCHEME_REQUIRED
и FILTER_FLAG_HOST_REQUIRED
при использовании FILTER_VALIDATE_URL
объявлены устаревшимиjson_encode
и json_decode
is_countable()
array_key_first()
и array_key_last()
Heredoc [1] и Nowdoc [2] требовали ставить закрывающий идентификатор первым в новой строке.
Пример:
$foo = <<<IDENTIFIER
the crazy dog jumps over the lazy fox
"foo" bar;
IDENTIFIER
Здесь закрывающий IDENTIFIER
должен быть первым символом на новой линии чтобы это работало. Кроме того, не должно было быть никаких других символов после закрывающего идентификатора (кроме ;
, который является необязательным).
RFC для PHP 7.3 предлагает убрать подобные требования для улучшения читабельности кода. Прежде всего чтобы добавить отступы при использовании heredoc/nowdoc
идентификаторов.
Полный список изменений в heredoc/nowdoc
синтаксисе:
Parse error: Invalid indentation - tabs and spaces cannot be mixed in .. on line ..
.heredoc/nowdoc
выражения.Parse error: Invalid body indentation level (expecting an indentation level of at least ..) in .. on line ..
Вот сниппет, который использует новые возможности без нарушения новых правил:
$foo = ['foo', 'bar', <<<EOT
baz
- hello world! --
ahoy
EOT, 'qux', 'quux'
];
var_dump($foo);
На выводе будет:
array(5) {
[0]=>
string(3) "foo"
[1]=>
string(3) "bar"
[2]=>
string(29) "baz
- hello world! --
ahoy"
[3]=>
string(3) "qux"
[4]=>
string(4) "quux"
} `
Обратите внимание, что отступы используемые в декларации при помощи heredoc
не отображаются в выводе var_dump()
, и мы продолжили перечисление элементов массива после EOT
идентификатора.
RFC [3], обсуждение на Externals.io [4], реализация [5]
Пока вы не используете набор идентичных heredox/nowdoc
идентификаторам символов в качестве начала строки, вы на коне.
$foo = <<<HELLO
HELLO_WORLD <-- это не будет приниматься за окончание строкового литерала
HELLOWORLD <-- и это не будет
HELLO WORLD <-- а это будет
HELLO;
Если у вас имеется heredoc/nowdoc
синтаксис подобный вышеописанному, отмечу, что с PHP 7.3, PHP воспримет первый HELLO
литерал и выдаст ошибку на следующей строке. В более ранних версиях HELLO WORLD
не воспринимался как закрывающий идентификатор для heredoc. Спасибо /u/ImSuperObjective2 с reddit за указание на это [6]
Это простое изменение, которое разрешает использование конечных запятых в вызовах функций и методах. Это не влияет на декларирование.
Например, следующий синтаксис станет возможным:
// функция
foo('bar', 'baz',); // Обратите внимание на последнюю запятую после после 'baz'
В до-PHP-7.3 версиях фрагмент выше выбрасывает ошибку PHP Parse error: syntax error, unexpected ')' in .. on line ..
.
Вы не можете использовать более одной запятой в конце или использовать запятые для пропуска аргументов. В основном это изменение для функция с вариативными параметрами. Также с новыми правками синтаксис массива будет выглядеть более последовательным.
Обратите внимание, что Вы не можете использовать эту возможность в объявлениях функций/методов; это неправильно:
function foo($bar, $baz, ) { // nah, you can't do this.
}
RFC [7], обсуждение на Externals.io [8], реализация [9]
Никакого. Существующий код будет и дальше работать. Если у вас есть вызовы функций принимающие вариативные параметры, добавьте конечные запятые в эти места для удобства. Но использовать их везде — это явно перебор.
list()
Функция list()
[10] полезна для быстрого присвоения значений переременным из массива. До версии PHP 7.3 не было возможным указать переменную по ссылке. До PHP 7.3 следующий фрагмент приводил к фатальной ошибке:
$arr = ['apple', 'orange'];
list($a, &$b) = $arr;
$b = 'banana';
echo $arr[1];
// Fatal error: [] and list() assignments cannot be by reference in .. on line ..
Ссылкаться на non-referencable
переменные нельзя: list($a, &$b) = [12, 14];
выдаст Fatal error: Cannot assign reference to non referencable value in .. on line ..
.
RFC [11], обсуждение на Externals.io [12], реализация [13]
Нет. Вместо того чтобы использовать list()
для заполнения нескольких переменных, я бы предложил вам воспользоваться value-объектами, чтобы сделать все проще. Они все равно будут передаваться по ссылке, но сделают ваш код намного чище.
image2wbmp()
объявлена устаревшейimage2wbmp()
[14] функция из расширения GD используется для вывода изображения в формате WBMP (Wireless Bitmap). В PHP 7.3 она объявлена устаревшей в пользу функции imagewbmp()
[15].
Если вы используете image2wbmp()
, то просто замените название функции на imagewbmp
и все будет хорошо! Более 5,500 упоминаний image2wbmp()
[16] на github против более 39,300 упоминаний imagewbmp()
[17]. Похоже, команда разработчиков PHP убирает редкоиспользуемые функции, чтобы минимизировать воздействие.
RFC [18], обсуждение на Externals.io [19], реализация [20]
Если вы используете функцию image2wbmp()
, замените вызов на imagewbmp
. Воспользуйтесь автоматизацией, которая сможет изменить это за вас.
FILTER_FLAG_SCHEME_REQUIRED
и FILTER_FLAG_HOST_REQUIRED
при использовании FILTER_VALIDATE_URL
объявлены устаревшимиЭто движение вперед. Когда вы используете filter_var($var, FILTER_VALIDATE_URL)
, есть два дополнительных флага, которые можно поставить для обеспечения строгой проверки URL-адреса: FILTER_FLAG_SCHEME_REQUIRED
и FILTER_FLAG_HOST_REQUIRED
.
Начиная с версии PHP 5.2.1 оба этих флага применяются неявно вне зависимости установлены они или нет.
Если ваш код использует эти флаги, просто удалите их и будет хорошо. На данный момент существует более 5000 результатов поиска на github с их использованием.
RFC [21], обсуждение на Externals.io [22], реализация [23]
Так как оба этих флага объявлены устаревшими, вы увидите уведомление вроде:
Deprecated: filter_var(): explicit use of FILTER_FLAG_SCHEME_REQUIRED and FILTER_FLAG_HOST_REQUIRED is deprecated in ...
Все, что вам нужно сделать — просто удалить два флага, т.к. они и так подразумеваются при использовании FILTER_VALIDATE_URL
.
Функция define()
позволяет объявить константу в регистро-независимом режиме. Вы должны явно объявить константу с учетом регистра, передав третьим параметром функции true
. Это не поведение по-умолчанию и наверняка не согласуется с возможностью объявлять константы через ключевое слово const
.
define('Foo', 'Bar', true);
Приведенный выше код будет выбрасывать уведомление об устаревании: Deprecated: define(): Declaration of case-insensitive constants is deprecated in ...
Кроме того, при попытке получить доступ к константам, которые были объявлены в режиме без учета регистра (FOO
), вы увидете довольно полезное предупреждение: Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "Foo"
RFC [24], обсуждение на Externals.io [25], реализация [26]
Вам придется идти в базовый код, туда где объявляются регистро-независимые константы и последовательно исправлять. Крайне маловероятно, что не будет никаких проблем с этим, потому что отловить все варианты использования довольно трудозатратно, но в результате код станет понятней.
Я не нашел на github примеры подобного использования, но как минимум Drupal и WordPress (два довольно старых и зрелых проекта в PHP) имеют регистро-независимые константы.
json_encode
и json_decode
Одно из моих любимых. Все эти годы json_encode()
и json_decode()
молчали об ошибках в PHP-переменных или json-строках, что приводило к забагованному коду. Этот случай даже был в знаменитой критике PHP: Фрактал плохого дизайна [27].
json_decode
возвращает null для невалидного ввода, при том, что null — абсолютно верный объект для декодируемого JSON'а. Эта функция абсолютно ненадёжна, если вы конечно не вызываетеjson_last_error
каждый раз при её использовании.
Потребовалось 6 лет после того поста в блоге и у нас появилась возможность получить ошибку о сбоях работы с json:
try {
json_decode("{", false, 512, JSON_THROW_ON_ERROR);
}
catch (JsonException $exception) {
echo $exception->getMessage(); // выводит "Syntax error"
}
Новый JsonException
является наследником от Exception
, а также константа JSON_THROW_ON_ERROR
и сам JsonException
находятся в глобальном пространстве имен.
Я настоятельно рекомендую вам начать использовать эту функцию. Есть сторонние библиотеки, такие как daverandom/exceptional-json [28], реализующие аналогичную функциональность для версий PHP 7.2 и ниже. С появлением этой функции в ядре PHP, вы можете удалить этот пакет и тонны некрасивого шаблонного кода с вызовом json_last_error()
в каждом месте где вы работаете с json.
RFC [29], обсуждение на Externals.io [30], реализация [9]
Никакого, если вы не используете собственное исключение и/или константу с такими же именами.
is_countable()
В PHP 7.2 достаточно много устаревших и забагованных функций. Если вы в PHP 7.2. вызываете count()
с использованием не-countable
переменной, то PHP выведет предупреждение об этом. В общих правках [31] было предложение проверять получаемую перменную на countable
до ее использования в count()
.
countable
-переменной является массив или объект реализующий Countable
интерфейс. Так как при проверке будет использоваться много шаблонного кода, в PHP 7.3 появилась новая функция is_countable()
, проверяющая переменную на… ну… возможность использования с count()
.
Я написал полифил для is__countable() [32], если вы хотите начать использовать эту возможность уже сейчас.
RFC [33], обсуждение на Externals.io [34], реализация [35]
Пока не объявлена своя собственная функция is_countable()
, проблем не будет.
array_key_first()
и array_key_last()
В PHP существует 75 различных функций для работы с массивами, но до сих пор не было простого способа получить первый и последний ключи массива без изменения указателя массива или перебора всех ключей (через array_keys()
) и зачем получения первого/последнего значения.
Появились две новые функции, array_key_first()
[36] и array_key_last()
[37] позволяющие это делать.
В RFC также предлагалось добавить array_value_first()
и array_value_last()
, но эта часть не прошла голосование.
RFC [38], обсуждение на Externals.io [39], реализация [40]
Если вы не объявляли свои собственные array_key_first()
и array_key_last()
функции, то проблем не возникнет.
PHP использует Perl Compatible Regular Expressions или коротко PCRE в библитеке для работы с регулярными выражениями. С версии PHP 7.2 используется 8.x версия легаси-библиотеки PCRE, а в PHP 7.3 уже будет использоваться PCRE2. Обратите внимание, что PCRE2 считается новой библитекой, хотя в значительной степени совместима с PCRE (8.x).
Новая библитека более агрессивна в валидации паттернов и может привести к ошибкам в существующем коде. Следующий фрагмент будет невалидным с PHP 7.3:
preg_match('/[w-.]+/', '');
PHP выбросит предупреждение Warning: preg_match(): Compilation failed: invalid range in character class at offset 3
.
Проблема с шаблоном: чтобы это работало дефис должен быть перемещен в конец или экранирован.
preg_match('/[w-.]+/', '');
Приведенный выше код отлично отработает не только с PHP 7.3, а также и с более старыми версиями. В новом паттерне дефис экранирован -
в -
. Это самая распространенная проблема из всех с которыми можно столкнуться при решении вопросов совместимости.
Это довольно незначительное изменение, но есть шанс, что все пойдет не так. Сообщение об ошибке указывает на точное положение символа в регулярном выражении. Убедитесь, что тщательно проверили свой код. Проверьте ваши регулярные выражения на совместимость с PCRE2 синтаксисом через Regex Buddy
или другой подобный софт. Дополнительные сведения смотрите в описании PCRE2 синтаксиса [41] и устаревшего PCRE синтаксиса [42].
RFC [43], обсуждение на Externals.io [44], реализация [45]
Так как PCRE2 более придирчив и строг к шаблонам, некоторые из ваших preg_match()
и подобных вызовов могут не работать. Исправление варьируется от простого обновления шаблона (например, заэкранировать дефисы) до переписывания шаблонов. Убедитесь, что все ваши тесты проходят.
Автор: iGusev
Источник [46]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/291698
Ссылки в тексте:
[1] Heredoc: http://php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc
[2] Nowdoc: http://php.net/manual/en/language.types.string.php#language.types.string.syntax.nowdoc
[3] RFC: https://wiki.php.net/rfc/flexible_heredoc_nowdoc_syntaxes
[4] обсуждение на Externals.io: https://externals.io/message/100891
[5] реализация: https://github.com/php/php-src/compare/master...tpunt:heredoc-nowdoc-indentation
[6] указание на это: https://www.reddit.com/r/PHP/comments/8dbjco/whats_new_and_changing_in_php_73/dxm5nyx/
[7] RFC: https://wiki.php.net/rfc/trailing-comma-function-calls
[8] обсуждение на Externals.io: https://externals.io/message/100837
[9] реализация: https://github.com/php/php-src/commit/b591c329ee3129adbdc35141bb1542d119f7a2a1
[10] list()
: http://php.net/manual/en/function.list.php
[11] RFC: https://wiki.php.net/rfc/list_reference_assignment
[12] обсуждение на Externals.io: https://externals.io/message/98053
[13] реализация: https://github.com/php/php-src/commit/6d4de4cf0582cf33848826ab78aae58077dc2dea
[14] image2wbmp()
: http://php.net/manual/en/function.image2wbmp.php
[15] imagewbmp()
: http://php.net/manual/en/function.imagewbmp.php
[16] 5,500 упоминаний image2wbmp()
: https://github.com/search?l=PHP&q=image2wbmp&type=Code
[17] 39,300 упоминаний imagewbmp()
: https://github.com/search?l=PHP&q=imagewbmp&type=Code
[18] RFC: https://wiki.php.net/rfc/image2wbmp
[19] обсуждение на Externals.io: https://externals.io/message/102025
[20] реализация: https://github.com/php/php-src/pull/3247
[21] RFC: https://wiki.php.net/rfc/deprecations_php_7_3
[22] обсуждение на Externals.io: https://externals.io/message/102394
[23] реализация: https://github.com/php/php-src/pull/3322
[24] RFC: https://wiki.php.net/rfc/case_insensitive_constant_deprecation
[25] обсуждение на Externals.io: https://externals.io/message/102389
[26] реализация: https://github.com/php/php-src/pull/3321
[27] PHP: Фрактал плохого дизайна: https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/
[28] daverandom/exceptional-json: https://packagist.org/packages/daverandom/exceptional-json
[29] RFC: https://wiki.php.net/rfc/json_throw_on_error
[30] обсуждение на Externals.io: https://externals.io/message/100494
[31] общих правках: https://www.drupal.org/project/drupal/issues/2885610
[32] полифил для is__countable(): https://github.com/Ayesh/is_countable-polyfill
[33] RFC: https://wiki.php.net/rfc/counting_non_countables
[34] обсуждение на Externals.io: http://externals.io/thread/350
[35] реализация: https://github.com/php/php-src/pull/2185
[36] array_key_first()
: http://php.net/manual/en/function.array-key-first.php
[37] array_key_last()
: http://php.net/manual/en/function.array-key-last.php
[38] RFC: https://wiki.php.net/rfc/array_key_first_last
[39] обсуждение на Externals.io: https://externals.io/message/102245
[40] реализация: https://github.com/php/php-src/pull/3256
[41] PCRE2 синтаксиса: http://pcre.org/current/doc/html/pcre2syntax.html
[42] PCRE синтаксиса: http://pcre.org/original/doc/html/pcresyntax.html
[43] RFC: https://wiki.php.net/rfc/pcre2-migration
[44] обсуждение на Externals.io: https://externals.io/message/100905
[45] реализация: https://github.com/php/php-src/pull/2857
[46] Источник: https://habr.com/post/422507/?utm_campaign=422507
Нажмите здесь для печати.