Pull to refresh

Comments 68

Зачем вообще использовать типизацию, если теперь все можно переопределить? Откуда ушли, туда и вернулись.
Переложили обязанность на разработчиков. Раньше вообще было мало возможностей контролировать типы. А теперь хотят сделать «Хочешь — контролируй, Хочешь — чуть меньше контролируй, а хочешь — вообще забей»
Возможно, это и правильно, пока что сложно сказать.
Сначала тоже возмутил этот шаг назад, но по факту, в реальности не так часто приходится использовать принцип подстановки Лисков. Как правило, там где я явно ожидаю объект класса A — объект класса B, расширяющий его, мне скорее всего не нужен. И даже более того — теоретически наследник может, сохранив реализацию контракта, переопределить внутреннюю реализацию настолько, что вызов наследника станет нежелательным.
UFO just landed and posted this here
когда расширяешь классы фреймворка или сторонней библиотеки от тебя уже не зависит выбор паттерна. а такое приходится делать чаще.
UFO just landed and posted this here
Я надеюсь RFC, где предлагается добавить mixed typehint отклонят.

Draft — 7.2 if RMs agree, otherwise 7.3

А можно узнать как вы реализуете паттерн реестра без mixed?

Просто не указывать возвращаемый тип. Псевдотип `mixed` в пыхе сам по себе является рудиментарным и вообще ничем не отличается от отсутствия декларации оного.
От отсутсвия декларации возвращаемого типа объявление mixed означает что разработчик точно знает что в данном месте возможен множественный возврат. Сейчас мне приходится в реестре возвращать без указания типа, но с пометкой в комментариях про bool|string|array, что само по себе является хаком.

Если мы уж стремимся перейти на строгую типизацию — нам нужно либо ее начать использовать везде, либо нигде.
Для этого в пыхе должны быть реализованы хотя бы составные типы (или хотя бы тайпалиасы), вида:
type some = bool | string | array;

function example(): some { ... }


В этом случае пропадёт надобность как самого mixed, так и iterable, и callable (хотя там есть внутренняя логика: Контекст должен быть действительным классом, а метод — существовать, но не суть).
Интересное решение. Спасибо. Не думал о таком.

я так и не понял почему это дело завернули(

А там и не было rfc с тайпалиасами, только с группировками «на месте»:
function getIterable(): array | \Traversable { ... }
//
function getArrayable(): array | \Traversable & \ArrayAccess { ... }


А это, как видно из простого примера — дичь. По-этому и завернули. Я бы тоже не хотел подобного функционала без возможности указывать алиасы.

Так что из этих всех обсуждений в релизе 7.1 остался только «костыль» для исключений:
try {
    // ...
} catch (\Throwable | \Exception $e) {
    // ...
}

может тогда тайпэлиасы запилить?)


type email = string;

function filterEmail(string $email): ?email
{
     // ...
}

а уже потом форсить union types.

Выглядит так же как mixed тип. Вроде нужно, а вот нахрена — не понятно =)

Есть вот такой, более профитный вариант:
type email (string $input): string { 
    if ((bool)preg_match('/^.+?@.+?\..+?$/isu', $input)) {
        return $input;
    }

    throw new \InvalidArgumentException(...);
}

function filterEmail(string $email): ?email { ... }


Такой способ:
1) Решит проблему рантайм-типов (вроде callable в виде массива).
2) Имеет довольно понятный синтаксис (я просто заменил кейворд `function` на кейворд `type`)
+ В качестве бонусов:
3) Предоставит базовый механизм декораторов
4) Предоставит базовый механизм аннотаций
5) Кусок DbC

Единственное НО — берёт на себя слишком много возможностей.

В этом всем есть один минус: Вот у меня кусок кода с вызовом:


function filterEmail(string $email): ?email { ... }

и к сожалению мне надо смотреть что погромист подразумевал под своим type email. А какой-нибудь г*кодер будет писать


function filterEmail(string $email): ?stringed { ... } 

и из лаконичного названия я буду думать про строку, а создатель про array или object.

В этом всем есть один минус: Вот у меня кусок кода с вызовом:

И чем это отличается, допустим, от интерфейса `Stringable`? Кажется, что в именовании переменных и заключается первая из извечных проблем (вторая — это инвалидация кеша). Так что от этого никуда не уйти.
В интерфейс Stringable если придет тип stringed — это одна беда. Если в интерфейс Stringable будет приходить string или mixed — я хотя-б пойму что от меня ожидают.

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

Вроде нужно, а вот нахрена — не понятно =)

дает информацию анализатору типов. Пример надуманный но мне иногда надо. Скажем есть метод который принимает не просто всякую строку, а строку которую может родить только определенный метод/функция. И на данном этапе делать для этого VO на пустом месте я не хочу.

Есть подозрение, что твой пример довольно непродуманный.

Пример:
// class EmailSenderExample
public function send(email $receiver, message $body): bool { ... }

// usage
$sender->send(?, ?); // И что сюда передавать можно? Строки? тогда зачем эти "тайпалиасы"?
А это, как видно из простого примера — дичь.

Это не дичь, в ts вполне удобно, но type там тоже есть.


Выглядит так же как mixed тип.

Учитывая что он эквивалентен отсутствию типа вообще непонятно зачем он нужен...


Кстати я бы еще хотел видеть overload-инг методов, который с учетом типизации вполне возможен. Надеюсь когда-нибудь оно появится.

Не указывать возвращаемый тип = void | mixed. Void тип добавили, не вижу причин не добавить противоположный ему mixed.

эдакий кастыль для языка не умеющий в ковариантность типов. Позволяет вам в наследниках "ослабить" пред-условия.


Может быть когда-нибудь PHP научится разруливать это более красивым способом.

Устарел mbstring.func_overload

Интересно, и как теперь битрикс выкрутится? Они же требуют mbstring.func_overload = 2 в конфиге php прописывать?

P.S. задал вопрос в техподдержку — вдруг ответят?
[sarcasm]не обновляйте php в этом году, а мы пока грязный хак выкатим[/sarcasm]
Так ведь пока просто deprecated ;). А к 8-ке перепишут.
А разработчикам с ворнингами жить?
Так как обновления безопасности для 7.1 до 1 декабря 2019 года и нет ускорения в 2 раза, то просто не будут поддерживать 7.2. А кто хочет — будет жить с ворнингами.

А ворнинги – самая большая проблема битрикс-разработчиков?

Включил на ~последней версии Битрикс24 коробочного режим отладки:
400 Notice
26 Strict Standart

1 Warning погоды не сделает, а учитывая то, что они поддержку 7.1 сделают не раньше середины 2018 года, то я бы не стал из-за этого переживать.
UFO just landed and posted this here
UFO just landed and posted this here
Ох как я ждал этого. Но битриксу пофигу, они так и останутся на 5,3 версии, потому что они не хотят ломать обратную совместимость (именно поэтому они не могут уже лет 5 как внедрить свое новое ядро). А не хотят ломать, потому что кормятся с маркетплейса, соответственно, если сломают то потеряют текущие расширения (а большинство разработок там откровенно заборшены) и потеряют деньги. Короче если битрикс не переосмыслит хотя-бы эту ерунду, то крах неизбежен
У них с 1 января 2018 года в технических требованиях минимальная версия PHP 5.6
А легче от этого не стало, потому что в битриксе не образумятся
Если ответят — процитируйте плиз, было бы интересно.

Никакой особой непреодолимой сложности возникнуть не должно. Делается буквально следующее:


  1. Заменяются все вызовы функции тип strlen, substr, и т.д. на mb_strlen, mb_substr и т.д.
  2. Вызовы функций mb_orig_strlen, mb_orig_substr и т.д. остаются в коде «как есть»
  3. Добавляются куски вида if (!function_exists('mb_orig_strlen')) { function mb_orig_strlen(...) {...}}
  4. В git hook добавляется проверка, что функции без префиксов не используются
  5. Плавно обновляемся на новую версию PHP
  6. Через полгода, когда все уже привыкли к новым правилам, наоборот запрещаем писать с префиксом mborig… (контролируя это с помощью git hook) и автоматически удаляем префикс mborig там, где он используется
  7. После последней замерженной ветки с этими новыми правилами, делаем финальное удаление mborig из кода и в git hook запрещаем использовать этот префикс в новом коде
  8. Выпиливаем if (!function_exists('mb_orig_...')) { } из кода
  9. Мы успешно итеративно перешли с mb.func_overload != 0 на mb.func_overload = 0
repeat this after each Bitrix update?

Почему? Это однократная процедура, как битриксу обновиться со старой версии на новую.

у них css фал из трех строк написан пятью людьми. О чем вы))) Они это не могут сделать уже лет этак много

Учитывая, что они не брезгуют менять кодировку файлов(если я не ошибаюсь, в маркетплейсе все на cp1251), можно и патчить все скачанные исходники.


Недавно возникла проблема с очередной библиотекой, патчить вручную было лениво, в итоге родился скрипт https://gist.github.com/oWeRQ/6d2514409e84f863122d07ddb8a2878d см. function mbo_patch и совсем экспериментальный вариант с рекурсивной обработкой при подключении (через include mbo_virtual('...php');)

<sarcasm>Здорово, PHP 5.6 вышла всего то в 28.08.2014, так классно, что за ~4 года они дошли до этой версии</sarcasm>
P.S. На этом графике даже нет PHP 7.2, хотя 08.08.2017(когда была опубликована статья) уже был PHP 7.2.0 Alpha 3 от 06.08.17. То есть они уже знали что он есть, но планировать не стали.
Это минимальная поддерживаемая версия. А так на 7-ке уже давно работает.
Добавлен отладчик PDO Prepared statements

Ура! Как их мне не хватало в своё время!
Ещё бы нативную поддержку тредов впилили бы…
В ядро PHP добавлена Libsodium

Таким образом PHP станет первым языком программирования с полноценным современным набором криптографических функций в базовой поставке. Для сравнения, язык Go 1.8 поддерживает X25519 и ChaCha20-Poly1305 в основном стеке TLS, но не предоставляет в стандартной библиотеке средств для обособленного использования современных криптографических алгоритмов на уровне приложения, для использования которых требуется установка дополнений. Другие проекты, такие как Ruby, Erlang и Node.js до сих пор основываются на OpenSSL, предлагая классические RSA и AES в режиме ECB без аутентификации шифротекста.
Оптимизирована работа встроенной функции in_array() с помощью поиска хеша в перевернутом массиве.

Подскажите, что это значит? Теперь нет смысла самостоятельно переворачивать массив для быстрого поиска? Неужели теперь у каждого массива есть хеш-таблица значений?

Оригинал:
Added ZEND_IN_ARRAY instruction, implementing optimized in_array() builtin function, through hash lookup in flipped array. (Dmitry)

Вот сам коммит:
Added ZEND_IN_ARRAY instruction, implementing optimized in_array() builtin function, through hash lookup in flipped array
После него была пара фиксов:

Optimizer support for ZEND_IN_ARRAY

Fixed ZEND_IN_ARRAY related issues
В PHP 7.4 будут изменены ...

А где-то еще упоминается PHP 7.4?

"Добавлена возможность перегружать абстрактные функции (RFC)".


Может всё-таки переопределять?

Кажется, грань между этими терминами очень тонкая.

Почему?
Грань очно толстая, в PHP, как в языке с динамической типизацией не может быть перегруженных функций.
Переопределение — это, по сути, исчезание родительской функции у класса и возможность ее вызвать только через приведение типа.
Перегрузка — это добавление функции и разрешение в зависимости от аргументов.
В общем, разница очень большая.

PHP7 это конечно хорошо, но зачем мы пишем так, как будто PHP мертвый, практически все сайты используют этот серверный и далеко сложный язык, я бы не сказал что PHP простой, он далеко не простой, может база простая, но не сам язык. Поэтому я считаю что нельзя PHP ставить во второй ряд рядом с PHYTON и GO.
PHP существует и будет существовать, потому что это скорее самая центральная ядро в серверной разработке, а как мы все знаем, сервер — это центр всего нашего сайта, нету сервера, нету ничего!
это центр всего нашего сайта, нету сервера, нету ничего!

в последние годы наблюдаются тренды децентрализации (блокчейны) и serverless архитектуры. Так что… поглядим посмотрим.

Новая функция preg_replace_callback_array() позволяет писать более чистый код, когда требуется использовать функцию preg_replace_callback(). До PHP 7 при необходимости обработать разные регулярные выражения разными функциями, приходилось для каждой такой обработки писать отдельный вызов функции.
Не приходилось. Была возможность определить группу шаблонов с опцией «e» («eval»). Потом эту опцию выпилили и какое-то время такого способа действительно не было. У меня была переписка с кем-то из команды разработки ПХП в это время.

eval выпилили не просто так. Количество минусов использования этого варианта намного превосходит плюсы. А уж что говорить про "чистоту"… тут массив ссылок на анонимные функции, это более чем чисто.

Я и не говорю, что просто так. Я указываю на неточность в тексте.
"Конечно, давайте отправим SOLID в ад. Кто такая Барбара Лисков??? Какая-то безумная женщина? Конечно! Давайте разрешим ломать принципы и идеи".

Специально пошел перечитал solid, так и не понял как это он вдруг нарушается? Лисков, вообще не писала ничего про ослабление интерфейса. Зато согласно методологии контрактного программирования:


  1. Предусловия не могут быть усилены в подклассе.
  2. Постусловия не могут быть ослаблены в подклассе.

Собственно, первый пункт соблюдался раньше, и теперь соблюдается. Лишь дали возможность ослабить предусловия. Что касается второго пункта, то я думаю, что было бы неплохо дать еще и возможность усиливать постусловия. А пока — страдаем.

Ослабление предусловий/усиление постусловий это нормально, но предложенное изменение уж сильно ослабляет это самое предусловие. То есть например у нас может быть метод который принимает на вход Money и внезапно в наследнике мы можем туда совершенно спокойно передать int. Конечно же это было бы глупо, но когда сам язык ограничивает от этого, то как-то проще.


Так что либо автор цитаты не разобрался что есть LSP, либо он грустит о том что нет возможности указать более общий тип для аргумента, а не просто "убрать" его.

Строго говоря, отсутствие типа — это "самый общий тип из всех возможных". Это тот самый пресловутый mixed.
А вообще да, правильнее всего было бы добавить возможность именно ослабить тип.

Sign up to leave a comment.