Как стать автором
Обновить

Комментарии 68

Зачем вообще использовать типизацию, если теперь все можно переопределить? Откуда ушли, туда и вернулись.
Переложили обязанность на разработчиков. Раньше вообще было мало возможностей контролировать типы. А теперь хотят сделать «Хочешь — контролируй, Хочешь — чуть меньше контролируй, а хочешь — вообще забей»
Возможно, это и правильно, пока что сложно сказать.
Сначала тоже возмутил этот шаг назад, но по факту, в реальности не так часто приходится использовать принцип подстановки Лисков. Как правило, там где я явно ожидаю объект класса A — объект класса B, расширяющий его, мне скорее всего не нужен. И даже более того — теоретически наследник может, сохранив реализацию контракта, переопределить внутреннюю реализацию настолько, что вызов наследника станет нежелательным.
НЛО прилетело и опубликовало эту надпись здесь
когда расширяешь классы фреймворка или сторонней библиотеки от тебя уже не зависит выбор паттерна. а такое приходится делать чаще.
НЛО прилетело и опубликовало эту надпись здесь
Я надеюсь 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 года, то я бы не стал из-за этого переживать.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Ох как я ждал этого. Но битриксу пофигу, они так и останутся на 5,3 версии, потому что они не хотят ломать обратную совместимость (именно поэтому они не могут уже лет 5 как внедрить свое новое ядро). А не хотят ломать, потому что кормятся с маркетплейса, соответственно, если сломают то потеряют текущие расширения (а большинство разработок там откровенно заборшены) и потеряют деньги. Короче если битрикс не переосмыслит хотя-бы эту ерунду, то крах неизбежен
У них с 1 января 2018 года в технических требованиях минимальная версия PHP 5.6
А легче от этого не стало, потому что в битриксе не образумятся
Если ответят — процитируйте плиз, было бы интересно.
Вот и ответ
image

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


  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?
Кто-либо использовал assert() на практике?
Да, в фишинговых письмах регулярно приходит (например, как в kkblog.ru/phishing-spam).

"Добавлена возможность перегружать абстрактные функции (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.
А вообще да, правильнее всего было бы добавить возможность именно ослабить тип.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий