Pull to refresh

Comments 51

Забыли про опциональную поддержку AVX инструкций и новый GC (в 3+ раза ускорение). Ну и принудительный JIT регулярок (раньше нужен был флаг S).

UPD. Ах да, это же перевод с копипасты чейнджлога, не увидел сразу. Ну тогда вопросов, как говорится, у матросов — нет. =)

Блин, ваш комментарий более информативен, чем вся статья )

Новая библитека более агрессивна в валидации паттернов и может привести к ошибкам в существующем коде.

Крайне некрасиво со стороны разработчиков языка. Начать стоило с notice или warning, но так, что бы продолжило работать. А ломать уже в следующей версии. Что б можно было спокойно мигрировать и исправлять сообщения. А так придется выкладывать с риском. Для легаси-кода без тестов (вытянул его с php5.3+php4 до php7.2) — печально.


Да, я понимаю, что произошла смена библиотеки. Но всё же печально.

Для того, чтобы реализовать варнинги и/или нотисы нужно держать одновременно две разные версии библиотеки в ядре и фоллбечить с новой на старую. Считаете это нормально?

С другой стороны — эту проблему можно решить минут за десять. Ctrl+F -> «preg» и просто проверяете работоспособность регулярных грамматик. Поведение не должно было поменяться. Так что не вижу в этом никакой трагедии.
Считаете это нормально?

Да, это приемлимое решение. Сделать опцию — warning генерить новой либой, результат — старой. Да, падение производительности, но в некоторых случаях отсутствие сбоев важнее.


Ctrl+F -> «preg» и просто проверяете работоспособность регулярных грамматик.

Вы имеете ввиду в голове? Минут за 10 можно просмотреть пяток случаев. Я вот вижу тысячу вхождений у нас в проекте. Сделать можно, но не особо увлекательно.


Так что не вижу в этом никакой трагедии.

Потому что оцениваете объем работ в 10 минут.

Ну есть надежда, что умные идешки вскорости будут парсить по новому синтаксису и выводить ошибки. Ну кроме самых запущенных случаев, когда регулярка формируется динамически.

Ну фиг знает, возможно да. С другой стороны можно запилить скриптик:
1) glob по всем файлам
2) выдираем все регулярки из preg
3) делаем обычный preg_match на пустоту в try/catch
4) ловим кривые регулярки и исправляем


Кажется, что в этом случае действительно на 10 минут работы)

UFO just landed and posted this here
Это требует много времени, и непонятно, почему разработчики PHP должны его тратить.

По той же причине, по которой они тратят время на поддержание всей прочей обратной совместимости. По той же причине, по которой они бросают warning для undefined constant вместо Fatal.

Почти наверняка появится cli-инструмент, который достанет из вашего кода все регулярки, скопмилирует их и покажет отчёт.

Изменения неизбежны, но есть и будут появляться линтеры и всякие compatibility-чекеры, как было для PHP7.
Да, это приемлимое решение. Сделать опцию — warning генерить новой либой, результат — старой. Да, падение производительности, но в некоторых случаях отсутствие сбоев важнее.

Переходить на новую версию языка — это вам не лобио кушать (с)
Ни в одном более-менее серьезном проекте невозможна ситуация типа «Ого! Новый пых вышел! Давайте завтра на проме развернем!».
В целом, регулярки в проекте обычно присутствуют в довольно ограниченном количестве, легко ищутся и без проблем тестируются и исправляются. Не думаю, что в этом случае платить за обратную совместимость поддержкой двух библиотек разумно.
в сложном коде регулярки могут собираться из частей, поэтому есть смысл в промежуточной версии с notice/warning
Да, только особо печально, если проект имеет толстую папку "vendor"…
Ctrl+F -> «preg»

а потом вспоминаем, что часть регулярок хранится в одном месте, а выполняется в другом так:


preg_match($pattern, $subject);

А потом вспоминаем, что в итоге такая регулярка даже не в самом проект выполняется, а в одной из подключённых библиотек.

Так для этого собственно и есть ченджлоги и рекомендации по миграции между версиями. Я отчасти с вами согласен, но в любом случае при апдейте версии сначала лучше вычитать changelog, на тестовой среде довести всё до рабочего состояния и потом уже мигрировать боевую среду. Всё становится грустно в случае если легаси-код обфусцирован, в остальных случаях, даже говнокод можно спокойно отревьюить и поправить.

Я мигрировал легаси через пять версий (с 5.4). А в целом небольшая часть кода ещё с php4 тянется. Так что отчасти соглашусь — конечно мануалы по миграции помогают. Разумеется, changelog внимательно прочитан. По каждой версии.


А вот довести до рабочего состояния на тестовом библиотеку десятилетней давности — не так-то просто. К тому же нет смысла (она уже работает), не увлекательно и за это не заплатят. Миграция — это для разработчиков, что б на php5.4 не писать (обновил до 7.2). И исправлять старые библиотеки по warning в логах намного проще.


Попробуйте, например, использовать TEST_UNDEFINED_CONSTANT на 7.0 — получите notice. А в 7.2 — warning. Вот это правильный подход — ошибка постепенно растет в уровне, что бы дать всем возможность её исправить без слома совместимости. Скоро будет Fatal.


Или, например, использование в качестве конструктора функции с таким же именем (вместо __construct) — они не сломали сразу (а что, старый стиль, кому он нужен) — они сделали Deprecated. Можно спокойно по логам отловить и исправить. За это спасибо разработчикам языка.

Ну так вы же знали, что дефис — специальный символ и его надо экранировать. У нас в принципе любые предупреждения конвертируются в ошибки, чтоб не затягивать с исправлением.
Эм. Нет, дефис — это не специальный символ и его не надо экранировать.
Вообще, да, вы правы. Но в примере из статьи '/[\w-.]+/' он означает диапазон символов.
В примере статьи используется символ «минуса» ну или «тире», если в рамках грамматики говорим.

В примере используется тире (т.к. это часть PCRE интервалов):
/[\w-.]+/

А дефис — это вот так:
/[\w—.]+/


Ну т.е. чувствуете разницу, да? )

Гм, нет, это дефис часто заменяют минусом, а тире это другой символ (условимся, что сейчас нас интересует только среднее тире). Так-то диапазоны надо записывать через короткое тире, но даже в регулярках используют минус.

Вот именно, что любые предупреждения. А в данном случае никакого предупреждения нет. Сразу ошибка. И то, что я знал, что в будущем синтаксис сделают чуть строже (на самом деле конечно не знал), никак не поможет отправиться в прошлое и попросить неизвестных мне разработчиков учитывать это при написании библиотек.


Вы же понимаете, что в библиотеке есть такая потенциальная ошибка и она там была ДО того, как я вообще первый раз эту либу увидел? А значит никакое мое знание на качество этой библиотеки повлиять не могло.

Я настоятельно рекомендую вам начать использовать эту функцию.

Дадад, и писать каждый раз эту колбасу


json_decode($json, false, 512, JSON_THROW_ON_ERROR); 

вместо


Json::decode($json);

Это не означает, что нужно именно так писать. Я, например, использую обертку над json_decode() из guzzle:


/**
 * Wrapper for json_decode that throws when an error occurs.
 *
 * @param string $json    JSON data to parse
 * @param bool $assoc     When true, returned objects will be converted
 *                        into associative arrays.
 * @param int    $depth   User specified recursion depth.
 * @param int    $options Bitmask of JSON decode options.
 *
 * @return mixed
 * @throws \InvalidArgumentException if the JSON cannot be decoded.
 * @link http://www.php.net/manual/en/function.json-decode.php
 */
function json_decode($json, $assoc = false, $depth = 512, $options = 0)
{
    $data = \json_decode($json, $assoc, $depth, $options);
    if (JSON_ERROR_NONE !== json_last_error()) {
        throw new \InvalidArgumentException(
            'json_decode error: ' . json_last_error_msg()
        );
    }
    return $data;
}

В 7.3 будет тоже самое, только теперь в самом PHP

В каждом неймспейсе эту функцию определяете :)? И какую на самом деле функцию ожидают увидеть те, кто этот код читают?

Во всех современных фреймворках есть возможности для сериализации через обертки (например Symfony или Laravel) для безфреймворкового использования подойдет GuzzleHttp::json_decode() или любой другой свой вариант с обработкой на невалидность json.

В каждом неймспейсе импортируется если нужна в нём, а ожиданий не должно быть у читателей, если они не видят её в use и не видят \ перед именем в вызове. По сути это неопределённое в рамках файла поведение. Нужно код всего проекта изучать, чтобы более-менее уверенно ожидать что json_decode без \ в каком-то неймспейсе вызовет в итоге стандартную функцию
В 7.3 будет тоже самое, только теперь в самом PHP

Боюсь, вы не совсем поняли статью, которую переводили.
Для вашего удобства я выше процирировал код из неё.

Все понятно. Вы недовольны тем, что нужно будет писать чуть более длинную функцию с доп. параметрами:


Я настоятельно рекомендую вам начать использовать эту функцию.

Дадад, и писать каждый раз эту колбасу


json_decode($json, false, 512, JSON_THROW_ON_ERROR); 

вместо


Json::decode($json);

Ответ: нет, писать не нужно, потому что во всех библиотеках давно есть обертки, где все это уже написано. В RFC предлагается начать с малого и не ломать совместимость, для начала сделали так, затем будет изменено поведение по умолчанию:


Future Scope
As mentioned earlier, it may be desirable to deprecate the default behaviour eventually.
В 7.3 будет тоже самое, только теперь в самом PHP

...


писать не нужно, во всех библиотеках давно есть обертки

"У Рабиновича было собственное мнение, но он его категорически не разделял" :)

Либо это какой-то троллинг, либо я чего-то не понимаю. В языке была проблема, ее стали решать на уровне языка (а не костылей). В чем неправильность?

Речь не про язык, а про статью, которую вы переводили.
Для вашего удобства я цитировал ранее предложение из неё, с которым я не согласен.

Также о PHP 7.3 можно послушать в подкасте «Пятиминутка PHP» 5minphp.ru/episode36

В одном из следующих выпусков рассмотрим стратегии тестирования кода под новую версию PHP, подписывайтесь!
Есть надежда, что в язык когда-нибудь завезут именованные параметры? json_decode() c «самым нужным параметром в конце» ещё повезло, вот когда в Symfony нужна same-site кука, можно в полной мере почувствовать всю глубину:

new Cookie('foo', 'bar', 0, '/', null, false, true, false, Cookie::SAMESITE_STRICT)

Без PHPStorm-ских parameter hints вообще печалька.
Поэтому нужно использовать класс с параметрами вместо этого.
… и когда у класса есть параметры без значений по-умолчанию, получается бомба, которой для безопасной работы уже нужен builder и далее по тексту из «Effective Java 2nd Edition».
Добавление функций array_key_first() и array_key_last()


не прошло и пол-века )

Причём, вангую, подавляющее большинство использований будет в виде


$first_item = $items[\array_key_first($items)];
А зачем? Ну т.е. разве не проще ли написать?
$firstItem = \reset($items);


Или я не понял и это просто сарказм?
Не знаю был ли там сарказм. Но код выглядит более интуитивно. Плюс не трогает при этом внутренний указатель массива.
Написать может и проще, но это не чистая функция, а имеющая сайд-эффекты, последствия которых сложно предсказать в общем случае. Ну банально пришёл вам массив по ссылке параметром вашей функции, а где-то снаружи он уже был сначала сброшен, а потом указатель был сдвинут и функция вызывающая вашу функцию никак не ожидает, что вы сбросите указатель. Все, кто напишет \reset в своей функции, проверят можно ли это делать по всему стэку вызовов? Практика показывает, что далеко не все.
Как-то не зацепил релиз, он выглядит скорее как 7.2.1, т.е. работой над ошибками.
Но это радует
Забыли про опциональную поддержку AVX инструкций и новый GC (в 3+ раза ускорение).
7.0+ релизы это полностью работа над ошибками и ядром с перестраиванием потихоньку его в убершнягу с асинхронщиной, JIT, поддержкой FFI и прочими шутками из коробки, вместо работы над синтаксическими плюшками. А результат трудов, которые направлены на создание PHP 8 с некоторой периодичностью вливаются в основную ветку.

Например: Ребята работали над оптимизацией опкода, вынеся математические операции на сторону «фронтэнда» (т.е. части, которая занимается лексером, парсером и генерацией промежуточного кода без рантайма) и получилось, что такой код:

$a = 2 + 3;


Содержит ровно один опкод, который выводится во время компиляции, а не рантайма (под рантаймом я имею ввиду исполнение опкода): Присваивание (ASSIGN) переменной $a значения 5, а следствием этой оптимизации мы получили возможность писать:

class X {
    public const A = [1, 2, 3];
    public const B = [4, 5, 6];
    public const C = A + B;
}


Из чего можно сделать вывод, что конкатенация константных строк и прочее — тоже теперь совершенно, как говорят, бесплатные.
теперь возможно объявлять массив так?
$arr = ['1', '2', ];
массив так 100 лет уже объявлять можно
Угу, кажется, что с первых версий языка trailing comma допускается. По крайней мере в 4ке работало.
Короткая запись объявления массива появилась ещё в PHP 5.4, если мне память не изменяет
$arr = ['1','2',];

trailing comma в массивах точно не помню с какой версии, но тоже уже довольно давно есть.
Теперь trailing comma доступна в вызове функции. То бишь в 7.3 допустимо писать так:
$methodResult = $someObject->someMethod($parameterFirst, $parameterSecond,);
$functionResult = someFunction($firstParam, $secondParam,);
По поводу PCRE и image2wbmp, и отсутствию обратной совместимости.
Вот иногда хочется убить разработчиков php, за то что ломают обратную совместимость. Это всё специально сделано, чтобы люди не сидели без работы? Вот смотрю на Microsoft и радуюсь — в современном Windows заработает даже программа 20 летней давности.
Вот что им мешало оставить алиас на image2wbmp?
Что мешало разработчикам PCRE не ломать совместимость?
Почему эти индусы из php считают, что разработчикам делать нечего, как при каждом обновлении php вычитывать changelog и искать несовместимости в коде, из-за желания левой пятки какого-нибудь гика из разработки php что-то рефакторнуть или выбросить ненужную по его мнению функцию?

Причём сделали бы хотя бы какой-то tool, который бы искал все несовместимости с прошлых версий и сам их переписывал. Как php-cs-fixer-v2.phar, который умеет например устранять ошибку no_php4_constructor при миграции php4->7, но не умеет заменять preg_replace /e на callback аналог, из-за чего приходится глазами смотреть тысячи вызовов функции и тратить часы на переписывание и отладку. Который также не умеет умно заменять ereg_replace на preg_replace, split на explode, удалять ссылки & перед методами времён php4.
Sign up to leave a comment.

Articles