Пых – Telegram
Пых
8.27K subscribers
260 photos
14 videos
6 files
566 links
Блог Валентина Удальцова о разработке на PHP.

Хобот @phpyhobot
https://youtube.com/@phpyh
https://vkvideo.ru/@phpyh
https://news.1rj.ru/str/isPHPdying

Статистика: https://news.1rj.ru/str/INOTAROBOT?start=st1219340804

Для связи используйте личные сообщения канала.
Download Telegram
Функция для получения всех типов класса

Такая функция потребовалась мне для поиска обработчика объекта по типу. Генератор здесь позволяет не рефлексировать раньше времени.

https://3v4l.org/EOPjm
Пых
Ванлайнер для получения данных объекта без рефлексии https://3v4l.org/adhBn Что почитать на эту тему: • документацию по Closure::call(), • статью Accessing private PHP class members without reflection от @Ocramius.
Выяснилось, что в предложенном мной виде функция objectToArray неуниверсальна ☹️

Для объекта встроенного класса (например, DateTimeImmutable или stdClass) вызов Closure::call бросит ошибку уровня E_WARNING и вернёт null, так как замыкание нельзя привязать к области видимости встроенного класса.

"Встроенность" можно проверить через ReflectionClass::isInternal, а можно просто подавить ошибку и обработать null, выбирайте по религии ситуации 😉

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

Обновлённый вариант функции с рефлексией https://3v4l.org/2mtXC и без https://3v4l.org/RqDHu.
Не игнорьте .idea в проекте

До сих пор встречаю проекты, где в .gitignore есть правила типа .idea/, .vscode/ или *.swp, поэтому решил написать этот пост.

Представим, что каждый разработчик решил использовать свою IDE с уникальными временными файлами и предложил PR на изменение .gitignore. Думаю, проблема очевидна. Код должен быть IDE-агностик, то есть не зависеть от среды разработки.

Это элементарно достигается настройкой глобального .gitignore на машине разработчика. Каждый прописывает себе те исключения, которые необходимы для его ОС, IDE и прочих инструментов, а затем спокойно открывает любой проект, не боясь закоммитить лишнее.

Всего лишь две команды в чек-лист вашего онбоардинга...

git config --global core.excludesfile ~/.gitignore
echo '.idea/' >> ~/.gitignore
Уже месяц используем Composer 2 RC в продакшне, рекомендую!

Главное улучшение — это, конечно, превосходная скорость без всяких плагинов вроде hirak/prestissimo или symfony/flex.

Понравилась возможность выполнить composer require/remove <name> --dry-run и безболезненно узнать, что изменится.

Также меня заинтересовало, почему задепрекейтили мою любимую опцию --no-suggest. Пояснение "из уст" автора нашёл только в issue #8615: в новой версии предложения необъёмные и ненадоедливые.

Подробно об изменениях:
• на русском https://sergeymukhin.com/blog/composer-2-chto-novogo-i-izmenennogo,
• на английском https://php.watch/articles/composer-2.

composer selfupdate --preview
Параметры vs Аргументы

Параметр — это переменная в сигнатуре функции. В PHP параметры характеризуются именем, типом, позицией, значением по умолчанию, вариативностью (...) и возможностью передачи по ссылке (см. ReflectionParameter).

Аргумент — это выражение/значение, используемое при вызове функции.

Именно поэтому $reflectionMethod->getParameters(), но func_get_args и InvalidArgumentException.

На мой взгляд простой, но важный нюанс 👌
Завтра выступаю на PHPFest 🚀 с докладом про утечки памяти 💧

Буду говорить и лайвкодить на следующие темы:
• как следить за памятью в консольных командах;
• эффективная декомпозиция кода;
• copy-on-write;
• $real_usage в memory_get_usage();
• циклические ссылки наглядно;
• WeakReference, WeakMap;
• как следить за памятью в воркерах.

https://2020.phpfest.ru/lecture/3

Буду ждать вас на странице трансляции в 10:00 по Москве (в 14:00 по Новосибирску)!
Разыгрываю билет на PHPFest 2020!

Задача

https://gist.github.com/vudaltsov/4c1fe1c2c2ad0f2a3850f5ef228e00db

Перед вами код фабрики тяжёлых отчётов. Отчёт генерируется на лету по запросу. В процессе фабрика может быть вызвана несколько раз для одного и того же экземпляра данных, поэтому предусмотрен in-memory кэш. В качестве сервера используется RoadRunner.

Как отрефакторить код, чтобы память не текла в PHP 7? В PHP 8?

Условия участия

• Нужно прислать правильные ответы на оба вопроса через бота (не через личные сообщения).
• Ответ для PHP 8 должен отличаться от ответа для PHP 7.
• Ответы принимаются сегодня до полуночи по Москве.
• Чтобы повысить шансы, нужно прислать простое и лаконичное решение как можно раньше.

Приз

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

Удачи! 😊
Итоги конкурса!

Как я проверял ваши решения 🤓

Если ответ был текстовый, то я оценивал правильность идеи. Если ответ был кодом, то я тестировал его при помощи InMemoryCachingReportFactoryTest.php, предварительно адаптировав тест, если были изменены названия классов или добавлены зависимости. Если тест крашился из-за банальной ошибки (например, неинициализированного типизированного свойства), я такой ответ не засчитывал. Если в коде визуально были неточности, но мой несложный тест он проходил, я засчитывал. Думаю, это справедливо, всё-таки совсем непротестированный код на прод заливать не стоит 😉

Победитель 🏆

Первый правильный ответ пришёл от Andrew (@Groonya):
https://gist.github.com/aivchen/39a956afc47634c7f8bb2de4688aa7c1 (PHP 7),
https://gist.github.com/aivchen/5c8d51bed4188910ed34660c3b92fea0 (PHP 8).

Интересно, что в первом сниппете Андрея тоже есть неинициализированное свойство $reports, однако оператор ??= на это по понятным причинам не ругается, поэтому формально код корректный.

Пояснение от меня 💡

Эту задачу я рассмотрю сегодня в рамках своего доклада. Решение выложил отдельным видео на PHP Point. Присоединяйтесь к PHPFest через 2 часа по ссылке https://2020.phpfest.ru/showtime/, всех жду!
Сегодня в начале выступления была заминка из-за того, что у меня не работала команда bin/console demo в специально подготовленном для лайвкодинга проекте.

По скрину поймёте, почему 😂

Как известно, Symfony пробегает все файлы, зарегистрированные в DI как ресурсы, при прогреве кэша в dev. Соответственно, при автозагрузке демонстрационного класса App\Worker в конце файла запускался этот самый воркер и начинал свой бесконечный цикл. Добавил эти строки я на последнем прогоне доклада и конечно же забыл удалить, поэтому сегодня утром "подвисание" команды для меня было полной неожиданностью...

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

🤦🤦‍♂️🤦‍♀️🙈
😅 Я не смог вас сегодня отпустить без подробного разбора вчерашней задачи, поэтому записал по горячим следам небольшой ролик на PHP Point.

Помимо комплексного решения для PHP 7 и PHP 8 я рассказал про маленькую неочевидную особенность \WeakReference и продемонстрировал, как можно тестировать утечки в PHPUnit в стиле тяп-ляп.

https://www.youtube.com/watch?v=r1HDMu7nJh0
На сегодняшний день я участвовал пока только в трёх конференциях по PHP в качестве докладчика, и из них PHPFest отличился самым высоким уровнем организации.

Посудите сами, в результате созвона с командой PHPFest я купил нормальный микрофон, Ethernet-адаптер для стабильного соединения в офисе, и вместе мы добились качественного стриминга задолго до самой конференции.

Большое спасибо @seregazhuk за настойчивость и пунктуальность. После стольких прогонов никакая техническая проблема в моём сетапе не могла меня смутить, потому что я был на 110% уверен в своём докладе.

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

@phpfest, вы огонь, спасибо за такой высокий уровень, пожалуйста, не расслабляйтесь, а остальные — подтягивайтесь!
При помощи Generator::valid() можно проверить генератор на пустоту, не обходя его целиком.

После вызова $generator->valid() функция генератора начинает выполнение и доходит либо до первого yield (тогда valid возвращает true), либо до конца (valid возвращает false). Интересно, что в первом случае на генераторе можно вызвать rewind без каких-либо последствий, так как обход ещё не начался. Во втором случае генератор закрывается и обойти его уже нельзя.

Сравните: https://3v4l.org/LL8E9 и https://3v4l.org/jni5Y.
Я в начале своего пути 🐣
Завтра в 11 по Москве в пыхэфире Краснодар!

• 11:00 — Быстрый способ разобраться с легаси и начать жить (Сергей Жук, Skyeng)

• 12:00 — Автотесты: как тестировать нетестируемое (Артем Прозоров, ZeBrains)

• 13:00 — Как жить, если у тебя не хайлоад: истории из практики работы с реляционными БД (Валерий Горбачев, PHP Krasnodar)

Также в процессе стрима можно будет принять участие в квизе и выиграть билеты на PHP Russia, пхп-слонов и не только.

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

Темы задорные, постараюсь встать вовремя 😜
Пых
Завтра в 11 по Москве в пыхэфире Краснодар! • 11:00 — Быстрый способ разобраться с легаси и начать жить (Сергей Жук, Skyeng) • 12:00 — Автотесты: как тестировать нетестируемое (Артем Прозоров, ZeBrains) • 13:00 — Как жить, если у тебя не хайлоад: истории…
Цитирую @seregazhuk:

Не бывает кода, который потом понадобится. Выкидывайте! Есть гит, он всё помнит. Как правило, "код который понадобится" никогда не понадобится.

Я тоже советую чаще делать выбор в пользу удаления. Если коммиты атомарные и с хорошим комментарием, найти их в истории и восстановить не составит труда. А вот кода любого сорта, в том числе WTF-, непокрытого и потенциально уязвимого автоматически станет меньше.

https://www.youtube.com/watch?v=Uezd5ocJQ9I&t=1133
Build Stuff Software Development 2020 уже в эту среду!

Build Stuff проводят на этой неделе конференцию и предложили мне разыграть на канале 5 билетов. Мероприятие традиционно проходит в Европе, но в этом непростом году пройдёт онлайн.

Конференция будет в эфире три дня (11-13 ноября), и на ней обсудят все баззворды на свете от машин лёрнинга до девопса. Меня особенно заинтересовала секция Hiding The Lead (13 ноября в 11:00) Сэма Ньюмена, авторитетного автора книг по микросервисной архитектуре.

К сожалению, придумать хорошую задачу в этот раз не успеваю, разыграем 5 билетов рандомно 🎲

Заполняйте форму сегодня до полуночи, и завтра в Пыхтелке я объявлю победителей.
Завтра в 11 по Москве в пыхэфире Нижний!

• 11:00 — MySQL vs Postgres (Антон Робуль)

• 12:00 — Полезные привычки для программистов (Олег Скляров, Skyeng)

• 13:00 — Очередной проект: взлетит или нет (Сергей Пантюшин, ВодоходЪ)

Также в процессе стрима можно будет принять участие в квизе и выиграть билеты на PHP Russia, пхп-слонов и не только.

https://youtu.be/pe3b0DHVnq8
PHP 🎱

Уже завтра, за день до релиза, будет большой стрим про PHP 8 от Skyeng, PHP Russia и PHP Point!

В программе:
• дискуссия о развитии PHP с Альбертом Степанцевым,
• обзор новых фич восьмёрки от меня,
• Q&A с ключевыми разработчиками PHP Дмитрием Стоговым и Никитой Поповым.

Ведущие Александр Макаров и Роман Пронский.

Подключайтесь, общайтесь и задавайте вопросы! Начало в 19 по Москве 🕖

https://www.youtube.com/watch?v=QSszmWIrRyw
Встречаем PHP 8!

🔴 Трансялция на PHP Point: https://www.youtube.com/watch?v=QSszmWIrRyw.

🗺 Слайды моей презентации: https://vudaltsov.github.io/php8-slides/.
Прямо сейчас очень интересная дискуссия Дмитрия Стогова и Никиты Попова про типы, компиляцию, async/await, корутины и траекторию развития PHP.

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