PHP Дайджест № 222/2 (22 февраля – 25 марта 2022)

Дисклеймер: Нет, это не дайджест авторства Романа Пронского. К сожалению, у меня нет достоверной информации - будет ли выходить его дайджест далее.

Однако я взял на себя смелость временно продолжить дело Романа и написать новый дайджест за тот месяц, что прошел с выхода последнего.

Если Роман сможет и захочет далее продолжать свой дайджест - он сам решит, как использовать мой текст: взять в свой проект, как его часть или нет. На всякий случай я ставлю нумерацию дайджеста через дробь. Однако не претендуя при этом на продолжение оригинального проекта.

PHP

Вышли версии PHP 8.1.4, 8.0.17. Обновления в основном посвящены исправлению найденных багов.

RFC (Requests for Comments )

За прошедшее время было не так много событий вокруг RFC.

Allow null and false as stand-alone types

https://wiki.php.net/rfc/null-false-standalone-types

В этом RFC предлагается добавить в систему тайп-хинтинга PHP еще два типа: null и false. Данная возможность позволит писать примерно такой код:

class Foo {
    public null $nil = null;
    public function foo(null $v): null 
    { /* ... */ *}
}

// В стандартной библиотеке достаточно много функций, возвращающих int|false или string|false
// Например таких:
function strpos(string $haystack, string $needle, int $offset = 0): int|false
{ /* ... */ *}

На всякий случай предлагается запретить декларацию типа ?null - видимо, от греха подальше :)

В момент, когда писалась статья, RFC находился на голосовании. Однако его принятие не вызывает никаких вопросов - результат голосования составляет 38 голосов "за" и 0 (ноль, а не null!) "против".

Undefined Variable Error Promotion

https://wiki.php.net/rfc/undefined_variable_error_promotion

Очень интересное предложение, которое фактически сводится к запрету на использование не объявленных явно переменных в PHP.

Сейчас обращение к необъявленной ранее (например через операцию присваивания) переменной производит ошибку уровня E_WARNING, после чего значением переменной становится null, а код продолжает выполняться далее, со следующей строки.

В обсуждении будущего PHP 9 Никита Попов отмечал, что такое поведение - это существенная проблема: дело в том, что ошибки могут обрабатывать хэндлеры, неявно меняющие состояние виртуальной машины PHP совершенно непредсказуемым образом, в отличие от явного выброса и явной же обработки исключения.

В данном RFC предлагается заменить ошибку уровня E_WARNING на исключение класса Error. Голосование закончено, результат весьма предсказуем: 33 "за" и 8 "против", предложение будет реализовано в PHP 9.

Sealed Classes

https://wiki.php.net/rfc/sealed_classes

Новая возможность языка, появление которой, если предложение будет принято, возможно уже в PHP 8.2

Вкратце: возможность для классов (и интерфейсов) ограничивать список своих наследников (и реализаторов). Проще, наверное, показать на примерах:

sealed class Foo permits Bar 
{
  /* ... */
}

class Bar extends Foo
{
  /* обычное наследование, без особенностей */
}

class Baz extends Foo
{
  /* фатальная ошибка этапа компиляции, наследование не разрешено */
}
sealed interface HasPrice permits Product, Service 
{
  /* ... */
}

class Product implements HasPrice 
{
  /* реализация интерфейса разрешена */
}

class Service implements HasPrice
{
  /* реализация интерфейса разрешена */
}

class User implements HasPrice
{
  /* ошибка, реализация интерфейса не разрешена! */
}

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

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

Новости фреймворков

Symfony

Laravel

Yii

Ввиду того, что сервис OpenCollective более недоступен в России, сообщество фреймворка открывает дополнительный сбор пожертвований в сервисе Boosty: https://boosty.to/yiisoft

Отмечается, что разработка фреймворка замедлится из-за резкого (примерно в 5 раз) сокращения сумм пожертвований.

Дополнительная информация может быть найдена здесь.

Инструменты и библиотеки

Интересные статьи

Хабр

Другие источники

Подготовлено при активном участии сообщества телеграм-чата "PHP Russian Talks".

Замечания по текущему выпуску и предложения для следующего можете отправлять автору в личку или в указанный выше чат.

@AlexLeonov
03.04.2022 14:54 UTC
Первоисточник

Комментарии

@kirillbdev
03.04.2022 12:03 UTC
+4

Очень бы хотелось уже видеть типизированные массивы, по типу:

function foo(int[] $array): Foo[]

Может кто в курсе, есть ли движения в этом направлении? По RFC нашел что-то похожее со статусом decline

@AlexLeonov
03.04.2022 12:11 UTC
0

Пока такое возможно только при использовании статических анализаторов, например Psalm.

@karneds
03.04.2022 15:40 UTC
0

Пока обхожусь таким вариантом

function foo(int ...$array)
03.04.2022 15:46 UTC
0

Такой вариант создает достаточно большую нагрузку, проверяя типы списка аргументов в рантайме.

03.04.2022 16:00 UTC
0

Типизация в php в целом создаёт дополнительную нагрузку. Т.к. интерпретатору необходимо эти проверки осуществлять при исполнении

03.04.2022 17:34 UTC
-4

Слово «интерпретатор» не очень корректное, в остальном, конечно же, вы правы.

@Vilaine
10.04.2022 05:17 UTC
0
Такое может появиться только в форме
array<int>, Generator<int>
и т.д. Были существенные ограничения дизайна, последнее, о чем мне известно.
@TsarS
03.04.2022 12:40 UTC
0
  • PHPIDS: библиотека обнаружения атак на ваши веб-приложения

А что там последние коммиты 9 лет назад?

@AlexLeonov
03.04.2022 12:47 UTC
0

Ваша правда. Включил в дайджест, потому что она обсуждалась в PHP Weekly.

Уберу.

@greenkey
03.04.2022 13:28 UTC
+2

Top PHP Web Development Trends in 2022 - довольно спорная статья, утверждающая, что современные тренды в PHP это: использование версий 7.1 и 7.2 и фреймворков Laravel, CakePHP, CodeIgniter, Zend Framework.

Хах, упомянуть ларавел и не отметить симфони - это, как минимум, странно

@eandr_67
03.04.2022 19:02 UTC
+1
Вообще-то голосование по Sealed Classes уже закончилось и предложение отклонено — т.к. не набрало 2/3 голосов.
@AlexLeonov
03.04.2022 20:03 UTC
+1

Я не одним днем готовил этот текст, прошу прощения.

@SerafimArts
03.04.2022 21:15 UTC
+1
Предложение находится в стадии голосования и, в целом, за его принятие уже подано голосов больше, чем за отказ.

Нужно 2/3 что б принять =( Так что скорее всего зареджектят.


P.S. Ой, я слепой слоупок, выше коммент как раз про это. Оказывается уже голосование закончилось даже. Что ж, очень жаль. Придётся дальше покрывать все классы @internal и @psalm-internal

@arkamax
04.04.2022 01:27 UTC
+1

А может кто-нибудь объяснить, зачем нужен тип возврата null? Другими словами, если принимаем или возвращаем только null, то зачем его вообще принимать или возвращать? При наследовании его невозможно будет переписать (ошибка наследования). Единственный вариант - комбинированные типы с null (и вот их как раз можно было бы сузить в случае возврата или расширить комбинированным типом для параметров), но для этого узкого кейса уже есть nullable types. Что я упустил?

@mihteh
04.04.2022 06:24 UTC
0

Тоже пока не понимаю полезности типа null, нужен пример из реальной практики где это хорошо зайдет

@eandr_67
04.04.2022 07:19 UTC
+3
Nullable types — это когда значение либо единственного типа, либо null. А для тех случаев, когда значение может быть одного из нескольких типов или null, nullable types не применимы — необходимо явно прописывать null.

Нельзя написать:
?string|array
или
?string|?array

Надо:
string|array|null

А в стандартной библиотеке такие функции есть и если вводится типизация, то и библиотечные функции должны иметь типизированную сигнатуру.
04.04.2022 14:36 UTC
0

ОК, спасибо, согласен в случае комбинированных типов с двумя и более + null. Разве что такие варианты лично я обычно вижу как антипаттерн и чаще всего ищу альтернативы, но это уже вкусовщина, скорее.

@mepihin
04.04.2022 10:08 UTC
+1

Зачем Sealed Classes? Кто объяснит их реальное применение, а то кажется, что это какая-то избыточная штука, которой почти никто не будет пользоваться. Я просто реально не понимаю, зачем запрещать реализации классов и ограничивать наследников...

@BeMySlaveDarlin
10.04.2022 04:17 UTC
0

В данном случае более строгий контроль наследования. Чтобы пользователь кода не пихал твой класс куда попало. Упрощает конвенции в команде и объем мнемоническое нагрузки при ревью.

@greenkey
04.04.2022 10:10 UTC
+1

Symfony - убрали официальную документацию на русском языке.

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

@Flying
04.04.2022 11:13 UTC
+1

Что-то есть, например, здесь, но её актуальность и полнота под большим вопросом.

Собственно переводы и убрали потому что их очень сложно поддерживать в актуальном состоянии.

Также для ознакомления с Symfony сейчас, вероятно, лучше рекомендовать книгу. Вариант на русском с сайта убрали, но он есть, например, здесь.

04.05.2022 06:15 UTC
+1

Книга на русском языке была не до конца обновлена, поэтому её скрыли с сайта.

На днях перевод актуализировали, книга снова доступна.

@pudovMaxim
04.04.2022 19:21 UTC
0

Похоже, в php опять откат адекватности или я чего-то не понимаю.

Вроде только стали нормально типизировать по-человечески, и вот новый возвращаемый тип false. Чем им bool не угодил-то?

@eandr_67
04.04.2022 19:48 UTC
+1
Например, стандартная функция strpos возвращает либо целочисленный индекс (если подстрока найдена), либо значение false (если не найдена) — значение true она не может вернуть ни при каких обстоятельствах. Таких функций в стандартной библиотеке много, да и в пользовательском коде такой подход нередко встречается. Так что указание того, что функция может вернуть не любое значение типа bool, а либо значение отличного от bool типа (нормальное завершение), либо false (действие не выполнено), безусловно улучшает надёжность и читабельность кода.
05.04.2022 17:26 UTC
+1

Ага, а можно указать, что функция возвращает 42 и ничто иное?

Понимаю откуда ноги растут, но не понимаю зачем это нужно. Про null еще понять можно, это всё же своеобразный тип данных, но false - это же уже и есть данные, но никак не тип.

05.04.2022 18:56 UTC
0
но false — это же уже и есть данные, но никак не тип.

Почему?


Ну т.е. почему какой-нибудь кейс Red у enum Color { Red, Green, Blue } рассматривается как отдельный подтип типа Color, который в свою очередь уже enum, а вот enum bool { true, false } уже нет, например?)

06.04.2022 23:10 UTC
0
Много вы видели функций, которые возвращают 42 и ничего другого? Очевидно, что нет. А функции, возвращающие false (наряду со значениями других типов) и никогда не возвращающие true, в PHP на каждом углу. И выделение подмножества типа bool, содержащего единственную константу false, является отражением типичных практик написания PHP-кода.