Пых
8.26K subscribers
263 photos
16 videos
6 files
579 links
Блог Валентина Удальцова о разработке на PHP.

Хобот @phpyhobot
https://youtube.com/@phpyh
https://vkvideo.ru/@phpyh
https://t.iss.one/isPHPdying

Статистика: https://t.iss.one/INOTAROBOT?start=st1219340804

Для связи используйте личные сообщения канала.
Download Telegram
Как справедливо заметил в обсуждении @dimmount, есть еще четвёртый подход — Closure Table. Мы, кстати, тоже его используем, но я не знал, что это так называется 🙈

По сути, это денормализация материализованного пути в отдельную таблицу ancestor/descendant с заменой like на джойны и подзапросы, подробнее в статье другого автора.

https://habr.com/ru/post/193166/
Теперь канал можно поддержать 💵 на Patreon

Для фона долго искал что-то с глубинным смыслом 😂
На всякий случай оставлю тут исходное изображение.

https://www.patreon.com/phpyh
В PhpStorm наконец-то добавят поддержку Psalm и PHPStan 🎊

Предположительно, плагины войдут в релиз 2020.3, так что ждём сентябрьский EAP.

Впервые плагины оформлены в виде опенсорс-проектов на GitHub, так что мы можем наблюдать как на языке со статическим анализом реализуется поддержка внешнего статического анализа для языка без статического анализа 🤣 Если серьезно, то проекты можно использовать как эталоны для собственных плагинов.

Подробнее в блоге JetBrains: https://blog.jetbrains.com/phpstorm/2020/07/phpstan-and-psalm-support-coming-to-phpstorm/.

Как отчаянный псалмовец 😜 очень рад быть к этому причастным.
Во время карантина по просьбе
@pronskiy записал для команды обзорный скринкаст по фичам Psalm.
Обработка deadlock в Doctrine

Проблему взаимных блокировок в первую очередь надо решать исходя из контекста, где они возникают. Однако если дедлоки стреляют изредка, можно предусмотреть простой retry. Удобнее всего его реализовать как middleware для command bus и там поймать Doctrine\DBAL\Exception\RetryableException.

Помните, что после ошибки EntityManager закрывается. В Symfony его можно оживить вызовом метода resetManager() на сервисе @doctrine (автовайрится по интерфейсу Doctrine\Persistence\ManagerRegistry). После этого менеджер даже в извлеченном из контейнера сервисе не кинет The EntityManager is closed благодаря замене инициализатора в прокси.

Пример такого middleware для Symfony Messenger: https://gist.github.com/vudaltsov/945291b4e8a8800f669d478c8d66e8b8
Когда надо объединить n массивов, причём n >= 0.

array_merge([], ...$arrays)
Спасибо @andrewDemb за ценное замечание: начиная с PHP 7.4 array_merge может принимать 0 аргументов.

array_merge(...$arrays)

https://3v4l.org/nUEs7
И ещё одно важное уточнение, спасибо @shmaltorhbooks.

Распаковать в аргументы можно только список (индексированный массив). На текущий момент даже Psalm это не проверяет. Соответственно, в общем случае массив массивов нужно привести списку массивов при помощи array_values.

Финальный вариант для PHP >= 7.4: array_merge(...array_values($arrays)).

Для удобства эту конструкцию можно оформить в виде функции в проектном functions.php.

/**
* @template T of array
* @psalm-param array<T> $arrays
* @psalm-return T
*/
function merge_arrays(array $arrays): array
{
return array_merge(...array_values($arrays));
}


Так приятно, что комьюнити помогает 😊
Если вам вдруг когда-нибудь потребуется найти/заменить символы перевода строки (\r, \n, \r\n), например для нормализации, можно воспользоваться малоизвестным классом \R.

preg_replace('/\R/', PHP_EOL, "text\rwith\nvarious\r\nline endings\n\n")


https://3v4l.org/5cBcW
В обсуждении @ivan_tsirulev обратил внимание, что \R матчит более широкий спектр символов:

• новую строку \n,
• возврат каретки \r,
• подачу страницы \f,
• вертикальную табуляцию \v.

Пример: https://3v4l.org/6QU82.

Список всех управляющих последовательностей в документации PHP: https://www.php.net/manual/ru/language.types.string.php#language.types.string.syntax.double.

Подробнее о поиске символов новой строки через регулярные выражения в статье Никиты Попова: https://nikic.github.io/2011/12/10/PCRE-and-newlines.html.
Открытое собеседование #1 🎊
Cтрим в четверг, 16 июля, в 17:00 по Москве/Киеву/Минску


Роман @phpdigest и я @phpyh совместно проведём открытое собеседование с Патриком Фельдешем.

Начнём со знакомства, перейдём к PHP, пробежимся по SOLID и закончим где-то в архитектуре и вопросами из чата. В конце расскажем, что было хорошо, а что не очень, и прошел ли бы кандидат реальное собеседование.

Трансляция будет на новом YouTube канале PHP Point — подписывайтесь, чтобы не пропустить следующие проекты 😉

https://www.youtube.com/watch?v=FQNd9W3nb3A
Кеш или кэш?
Anonymous Poll
26%
кЕш
74%
кЭш
Понравилась статья Null is your friend, not a mistake.

Главный тезис: сама по себе концепция null не является ошибкой (в миллиард долларов), ошибочна система типов Java, которая считает null частью любого типа.

Для понимания. В PHP у нас с этим всё хорошо 😳: мы явно помечаем тип X как nullable при помощи символа вопроса ?X. В Java такого нет, переменная типа X может иметь значение X или null. Поэтому у новичков (которые не выбрали Kotlin) часто проблемы с NullPointerException, а в коде на Java присутствуют костыли @Nullable и @NotNull и/или "избыточные" проверки null != $obj.

https://medium.com/@elizarov/null-is-your-friend-not-a-mistake-b63ff1751dd5

За статью спасибо @Enleur.
Эффективно игнорим исключения в Psalm

Вчера счастью моему не было предела, когда в https://github.com/vimeo/psalm/issues/3286 через 3 месяца мне ответили, что в psalm.xml в разделе <ignoreExceptions> есть незадокументированный тег <classAndDescendants>. При помощи него уже давным давно можно игнорить исключение и все его подклассы. На скрине до и после 🤣

Игнорить следует unchecked исключения (подклассы RuntimeException, LogicException и Error). Ну и иногда можно позволить себе игнорить некоторые checked, чтобы не захламлять проект бесконечными @throws, которые едва ли можно как-то обработать.

Кстати, в PhpStorm в разделе Preferences > Languages & Frameworks > PHP тоже можно указывать, какие исключения считать unchecked.
Компонент или компонента фреймворка?
Anonymous Poll
94%
компонент
6%
компонента
Поиск и устранение утечек памяти в PHP с разбором реального примера

29 июля, в эту среду, в 18:00 я проведу стрим на канале PHP Point.

Примерный план:
• поговорим о видах утечек и инструментах для их поиска;
• установим один проблемный компонент Symfony и найдём в нём утечку;
• запилим быстрый фикс для проекта при помощи Compiler Pass;
• если успеем, сделаем Pull Request в репозиторий Symfony.

https://www.youtube.com/watch?v=NNMp-97rk9c
​​#MoreView #13 | Валентин Удальцов – Автор канала "Пых" и ведущий разработчик в Happy Job

Продолжаю брать интервью у людей из мира PHP. На этот раз в гостях Валентин Удальцов. Я познакомился с ним в процессе организации онлайн-собеседования PHP разработчика. После предыдущего интервью с Дмитрием Елисеевым я понял что мне интересно еще поговорить про PHP и я сразу вспомнил про следующего гостя:)

В четверг в 17.00 поговорим про PHP, архитектуру, Пых, музыку и многое другое в онлайн формате. Приходите, задавайте вопросы и выигрывайте пиццу за лучший вопрос:)

Подробнее о выпуске: amorev.ru/moreview-13-valentin-udaltsov
Ссылка на трансляцию: youtu.be/LOrb3m0FQdU
Как сделать тестируемым класс, использующий нечистую встроенную функцию PHP?

Очень просто — объявить функцию необязательным параметром конструктора.

final class Service
{
/**
* @psalm-var callable(): int
*/
private $time;

/**
* @psalm-param ?callable(): int $time
*/
public function __construct(?callable $time = null)
{
$this->time = $time ?? 'time';
}

public function do(): void
{
$time = ($this->time)();
}
}

$service = new Service();

$serviceForTesting = new Service(static fn (): int => 1234567890);


Не советую использовать либы-костыли типа php-mock/php-mock.
Через несколько минут я окажусь в гостях у Антона Морева на канале MoreView!

Буду ждать ваши каверзные вопросы 😅
По словам Антона, автор самого крутого вопроса получит 🍕

https://www.youtube.com/watch?v=LOrb3m0FQdU