Хэндлим тему | Дерепко – Telegram
Хэндлим тему | Дерепко
275 subscribers
50 photos
3 videos
1 file
56 links
Discussion group @handle_topic_chat
Contact with me @xepozz
Download Telegram
Forwarded from Test chan
😁6
💾 Ретро 2023
#оффтоп

Этот год уже всё, давайте следующий.

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

✈️ Побывал в Турции, Грузии, России, Тайланде. Где-то несколько дней, где-то значительное время жил и живу
🦷 Вырвал зуб 6-ку, который года 3 был в ужасном состоянии
❤️ Завёл этот канал и нашел своих первых подписчиков
Начал больше времени уделять социальной части и медийки
🏍 Научился кататься на мотоцикле
📱 Купил экшен камеру и айфон
✂️ Научился делать резки и склейки в DaVinci
8️⃣ Поучаствовал в ~ 8-х разных проектах в качестве разработчика
📺 Посмотрел сотни фильмов
🎧 В Яндекс.Музыке прослушал почти 100 тысяч часов музыки
💲 Заработал десятки тысяч $$$

Ретроспектива состоит обычно из двух шагов, поэтому второй шаг будет с планами на новый 2024:

😬 Вставить зуб, а лучше 2
💯 Сделать тысячу подписчиков в телеграмме
📺 Запустить канал про IT мемы в Instagram / TikTok и набрать тысячу подписчиков там
👨‍🏫 Запустить серию обучающих уроков по приготовлению Yii3 на Youtube
🗺 Определиться с местом для постоянного места жительства
👫 Наладить личную жизнь
💪 Заменить пивное пузо спортивными кубиками пресса
🤑 Найти дополнительный источник заработка, помимо основной работы
🐈 Завести кота
🖼️ Зарелизить Yii3
🤑 Начать зарабатывать $10 000/month

Пока так, дальше буду делить подробнее, приоритезировать, фильтровать и ставить чекпоинты.

А вы ставите цели на год и следите за прогрессом время от времени? 😉
С наступающим новым 2024 годом!

——

Передаю эстафету ретро Александру Макарову и Олегу Мифле
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍6🔥1
Календарь, как смысл жизни
#пост №6.

Как-то случайно набрёл на статью одного из моих прошлых коллег про календарь. Статья занятная. Автор крутой.

Как обычно, телега не может засунуть больше 2 тысяч символов в мое сообщение, поэтому выкинул пост в телеграф: https://telegra.ph/Kalendar-kak-smysl-zhizni-01-23
1👍4
Тестирования функций из стандартной библиотеки PHP и не только

#пост №7

Цель

Подмена (mock) функций, которые уже “загружены” в PHP еще до подгрузки Composer Autoloader, каких-либо include или других объвлений function name(){}

Подмена не только из под не пустого namespace, например App\Service\name , но и из корневого namespace: проще всего это сделать через use function name;

Проблема

Если объявить функцию с именем, которая уже существует в стандартной библиотеке PHP, то получим ошибку, что такая функция уже существует и переопределить её нельзя.

Можно было бы “выгрузить” её из памяти, но увы, выгружать из памяти функции в PHP нельзя.

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

Ресерч

В php.ini можно найти флаг disable_functions , которая принимает список имен функций, которые нужно “не объявлять” в недрах PHP.

Если использовать этот флаг, то php -ddisable_functions=time -r "echo time();" выкинет ошибку:


❯ php -ddisable_functions=time -r "echo time();"
PHP Fatal error: Uncaught Error: Call to undefined function time() in Command line code:1
Stack trace:
#0 {main}
thrown in Command line code on line 1

Fatal error: Uncaught Error: Call to undefined function time() in Command line code on line 1

Error: Call to undefined function time() in Command line code on line 1

Call Stack:
0.0000 389568 1. {main}() Command line code:0


Это и логично. Функции time больше нет. Но теперь ведь можно создать её самостоятельно?

Если объявить функцию самостоятельно, то ошибки больше не будет:

```shell
❯ php -ddisable_functions=time -r "function time() { return 123; } echo time();"
123%
```

Бинго!

Помещаем объявление функции в библиотеку, создаем State manager, через которого сможем управлять возвращаемым значение “123” и делаем пользователю интерфейс взаимодействия с этим менеджером.

Теперь, если пользователь захочет протестировать вызов time , то сможем самостоятельно указать требуемые значения. Время в будущем, в прошлом, 0, false, что угодно.

Но как быть, если нужно протестировать измененную функцию time лишь в одном тесте, а в других местах оставить всё как есть?

Можно так и сделать: State manager создает для всех тестов функцию, которая эмулирует стандартную time , а в нужном тесте наложить на общую эмуляцию частную.

Вроде всё логично и понятно. Можно накодить и наслаждаться тестированием.

Однако, а как эмулировать системное время? Если с различными полифилами от symfony всё понятно: можно создать какую-то функцию, которая будет базировать на другой функции, преобразовывать результат под новый формат и отдавать его.

Но на какой функции нужно базировать время?

DateTime`* классы? `
date() ? mktime ? hrtime ? А если их тоже отключить нужно?

Ba
sh! 🤪

PHP имеет возможность в любое время обратиться к своему старшему брату-башу простыми обратными кавычками: `command` . Результат будет строкой, но всегда можно "кастануть".

Для аналога time() команда `date +%s` .

Значит для State manager осталось написать только возможность использовать не статичное значение, а функцию, которая каждый раз будет выполняться.

Всё это и не только сделано в библиотеке xepozz/internal-mocker

Читаем доку по установке и первичной настройке, добавляем нужные файлы, вписываем следующую конфигурацию:


$mocker = new Mocker();
$mocker->load([
[
'namespace' => '',
'name' => 'time',
'function' => fn () => `date +%s`,
],
]);
MockerState::saveState();


——

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

——

Описание disable-functions: https://www.php.net/manual/en/ini.core.php#ini.disable-functions

Internal mocker: https://github.com/xepozz/internal-mocker/
1👍13
Хэндлим тему | Дерепко
Тестирования функций из стандартной библиотеки PHP и не только #пост №7 Цель Подмена (mock) функций, которые уже “загружены” в PHP еще до подгрузки Composer Autoloader, каких-либо include или других объвлений function name(){} Подмена не только из под…
Решил превратить пост дополнительно в статью на хабре: https://habr.com/ru/articles/797343/

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

Посты на индексируемом пространстве: хабр, медиум и прочие большие ресурсы хорошо подходят для продвижения твоих статей:
- матч по ключевым словам из поисковиков
- cross-reference от статьи к статье, по ссылкам внутри статьи
- знакомство с “чужой” аудиторией
- большая ротируемость просмотров

Выкладывать один и тот же текст на разные ресурсы – это очень грамотное продвижение. Но мне пока лень 🙂

——

Кстати, этот инструмент помог в Jetbrains php stubs исправить пару недочетов: раз и два.
А еще он хорошо подошел для тестирования функции flush() в Yii3.
🔥9👍2
Параллельные вычисления на PHP
#пост

Как сделать 1 000 HTTP запросов за 8 секунд?
А отправить миллион писем за 2 минуты?
А если без брокеров очередей и баз?

Сначала думал, что pcntl будет хорошим вариантом, но позже передумал.

Пощупал AMPHP и очень понравилось. Код выглядит максимально привычным, никаких расширений ставить не нужно, поддержка composer и всё типизировано.
Но я нашел проблему – документация практически отсутствует.

Как обычно, много текста в пост не влезло, поэтому закинул в телеграф:

https://telegra.ph/Parallelnye-vychisleniya-na-PHP-03-05

Да, здесь не про параллельные вычисления, но я захотел так назвать пост 😉
Если понадобится, могу поделиться полными результатами сравнения работы pcntl vs amphp: Генерировал 1 000 000 итераций, которые со случайной задержкой 1–10 сек. должны были выполнить операцию.

——

А пробовали ли вы асинхронные фреймворки?

@handle_topic
1🔥12👍3
Управление форматом ответов
#пост

Недавно в чате Yii Флудилочная @Kutuzov_ska столкнулся с проблемой разных ответов в dev и prod окружениях приложения на фреймворке Symfony. О проблеме можно почитать здесь.

Development

Как правило, когда мы разрабатываем приложение, мы хотим видеть как можно подробнее причину поломки нашего кода:

- Текст сообщения
- Файл, строку и код, где произошла поломка
- Stacktrace от точки входа в приложения до этой самой строчки
- Значения переменных, аргументов функций и прочее.

Обычно приложения с обработчиком исключений и ошибок это и делают: рисуют красивый UI, рисуют сниппет с ошибой и подсвечивают нужную строчку.

Даже в JSON API многие приложения конвертируют всё в JSON представление и клиенты этого API могут увидеть полный текст ошибки, stacktrace и т.п.

Production

Однако, в продакшене такое делать непозволительно опасно:

- Тексты ошибки дают злоумышленникам возможно эксплуатировать ваше приложение и найти уязвимости
- Stacktrace может раскрыть вашу внутреннюю структуру приложения
- Значения переменных могут раскрыть ваши данные для доступа к тем или иным сервисам

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

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

Для клиентов API порой удобно завязаться на текст ошибки и сделать какое-то конкретное действие:

- Подождать какое-то время и отправить запрос заново
- Показать текст ошибки пользователю
- Выполнить какую-то логику, основываясь на тексте ошибки

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

Чтобы ваш клиент не показал пользователю ошибку


Fatal error: Uncaught TypeError: find(): Argument #1 ($id) must be of type int, string given


Стоит как-то разделять текст, который можно показать пользователю и текст, который стоит скрыть за стандартным текстом HTTP кода: Internal server error, Bad request и другие.

Обработчик ошибок

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

В Yii2 есть концепция HttpException: есть несколько базовых классов, отражающие соответствующий HTTP код исключения и возможность задать свой текст ошибки, который увидит клиент. Подробнее можно почитать здесь: ссылка на документацияю.

В Symfony приложениях тоже есть аналогичный подход.

Exception Mapper

В своих проектах я предпочитаю написать свой mapper исключений в выводимый ответ:

- Создаю класс, который встраивается в логику обработки исключений
- Сформирует нужный мне формат ответа с дополнительными кодами и текстами
- Будет заниматься прочими удобствами для development окружения

Похожая схема есть и в Yii3: ссылка на документацию.

В Yii3 http stack построен на базе PSR middleware, поэтому нужно лишь добавить middleware в стек и настроить класс формирования ошибок.

В Symfony http stack построен на событийной модели, и для похожего действия нужно написать свой обработчик события onKernelException.

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

Выглядит такой обработчик примерно так: ссылка на gist.

Имея собственный обработчик, этого позволяет мне внедрять множество коротких путей в разработке, уменьшая boilerplate кодовой базы. Выглядит очень просто и всегда можно изменить массово под требования.

——

Полезные ссылки:

List of http status codes
Yii Флудилочная

@handle_topic
1👍5🔥2
Remap – гидрация результатов sql запросов с преобразованием
#пост

Довольно часто мне приходилось делать raw sql запросы в БД для получения данных. Причин тому было несколько:

- Так быстрее
- Не нужно писать длинные билдеры
- Запрос часто менялся, проще всего переносить as-is из требований в код
- Подсветка синтаксиса в IDE
- Удобная отладка: скопировал в DB Viewer и запускаешь
- И многое другое

Зачастую в проекте уже была какая-нибудь ORM или Active Record, где всегда результат запроса был объектом с необходимыми свойствами и типами.

Однако работа с raw sql обычно заканчивалась перегоном массивом из одного метода в другой.

Это неудобно:

- Нет типизации параметров функции – array $data
- Нет типизации свойств – $data['user_id'] – int/string?
- Нет понятия наличия свойства в массиве вообще – $data['unknown_prop'] – ошибка, которую найдешь только при выполнении кода

Как-то давно общаясь в чате про Active Record в Yii3 ко мне пришло озарение, что AR – это всё еще сложно – нужно наследоваться от базового класса или подключать trait, где-то доставать фабрики и самое главное, всё равно raw sql не смапить в модельку.

К тому моменту hydrator из Yii3 был почти готов и я решил сделать Proof Of Concept обычного data-mapper, с использовать db и hydrator.

Вот что из этого вышло:

Remap

Библиотека содержит лишь 1 класс и делегирует работу по исполнению запроса в yiisoft/db. Создание объекта и его наполнение библиотека делегирует в yiisoft/hydrator.

Таким образом, логика выглядит линейной и понятной:

1. Выполняет raw sql запрос
2. Проходим построчно по результату запроса
3. Создаем DTO и наполняем его нужными полями

Всё это скрыто в методе Remap::map()

Пример работы с библиотекой:



final class Todo
{
public int $id;
public string $noscript;
public int $status;
public int $created_at;
}

$sql = 'SELECT id, noscript, status, created_at FROM todo WHERE id = :id LIMIT 1';
$params = ['id' => 1];

$remap->map(Todo::class, $sql, $params);


Remap::map()

Метод принимает первым аргументов класс, который нужно будет создать и наполнить.

Второй и третий аргументы – сам запрос и параметры для подстановки. Можно передать во второй параметр string $sql , а в третий array $params , а можно сразу во второй передать [$sql, $params]

Метод возвращает \Generator объектов. Это позволит обрабатывать большие объемы результатов запроса и не падать с нехваткой памяти.

Как вариант использования библиотеки я сразу подметил, что удобно было бы использовать класс, как AR и Query Builder, поэтому с легкостью вышеупомянутый пример можно превратить в следующее:


$remap->map(Todo::class, Todo::selectOne($id));
$remap->map(Todo::class, Todo::selectAll());


Использовать можно по-разному, поэтому для еще большего упрощения записи можно написать следующее:


$remap->map(...Todo::selectAll());


Статические методы в Todo в текущих примерах будут возвращать массив из нужных значений:

- [$sql, $params] в первом примере
- [self::class, $sql, $params] во втором примере

А использование yiisoft/hydrator позволило использовать Attributes для произведения дополнительных трансформаций. Например:


final class TodoModelHydrator
{
#[Data('id')] // В свойство $identifier запишется то, что лежит в id свойстве
public string $identifier; // дополнительно cast from int -> to string
#[Data('noscript')] // noscript -> text
public string $text;
public string $status; // int -> string
#[Data('created_at')] // created_at -> date_created
public string $date_created; // int -> string
}


Таким образом, результат запроса можно преобразовать под нужные конвенции объектов и не зависеть от устройства внешнего хранилища.

Причесал библиотеку, написал тесты, подкрутил Psalm на 1 уровень, тегнул 1.0.

Надеюсь эта библиотека поможет и вам. Буду рад любым предложениям по улучшению.

——

Полезные ссылки:

Remap
Использование атрибутов yiisoft/hydrator

@handle_topic
1👍11🔥7
#оффтоп

Хороший кейс, почему нужно писать свои программы быстро :)

Разбор, конечно, очень поверхностный, но сама история довольно интересная. Рекомендую к прочтению.
👍2
Forwarded from Авва
В мире компьютерной безопасности сегодня интересный день. Точнее, он начался вчера вечером, когда немецкий разработчик Андрес Фройнд опубликовал отчет о тайной лазейке (бэкдор), которую он обнаружил в новых версиях широко используемой библиотеки для сжатия liblzma (часть архиватора xz). Лазейка позволяет взломщикам заходить через SSH на системы, в которых установлены эти новые версии - к счастью, похоже, что это всего несколько дистрибутивов Линукса в их до-релизовых версиях.

Всех очень впечатлило, насколько эта лазейка была сделана хитро, и как взломщик или взломщики серьезно поработали над тем, чтобы замести следы:

- взломщик под именем/псевдонимом Jia Tan почти два года (!) участвовал в разработке опенсорсного пакета xz, завоевал доверие его мейнтейнеров и получил доступ к прямому коммиту в его репозиторию. Он сделал больше 700 коммитов, лишь малая часть которых медленно подготовила код для лазейки

- основной код лазейки спрятан в тестовых файлах проекта (примеры "плохих" и "хороших" архивов)

- исходный код, который включает лазейку в собственно библиотеку, вообще не является частью основной репозитории в Github. Он спрятан в тар-архивах двух последних релизов, которые обычно используются мейнтейнерами дистрибутивов. То есть есть таг релиза, есть архив, якобы собранный из репозитории в момент этого тага, но на самом деле в нем есть крохотная добавка; в самой репозитории ее нет

- эта добавка прячется в конфигурационной магии autoconf, которую все ненавидят лютой ненавистью и никто никогда не заглядывает внутрь

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

- внутри библиотеки код лазейки заменяет несколько функций, которые работают с символьными таблицами библиотек во время их подгружения. Затрачены специальные усилия, чтобы имена функций не появлялись в двоичном коде. Что именно дальше делает код лазейки, до конца еще не ясно, но он обрабатывает сам символьные таблицы библиотек, и видимо находит то, что имеет отношение к SSH серверу, и что-то там заменяет. Это еще проверяют сейчас.

- интересно, что openssh, стандартный SSH-сервер под линуксом, не использует библиотеку liblzma, в которую вставили эту лазейку, но несколько популярных дистрибутивов добавляют в него поддержку уведомлений системы, systemd, а библиотека libsystemd уже в свою очередь использует liblzma.

- после того, как вышли версии библиотеки с ошибкой, несколько разных людей с незамеченными до того именами (очевидно, альты взломщика или сообщники) стали открывать запросы в разных программах и пакетах сделать апгрейд на эти новые версии, и в некоторых случаях преуспели

Взломщик допустил только одну ошибку: код лазейки, когда он работает как часть openssh, довольно медленно обрабатывает эти символьные таблицы, или что он еще там делает, и даже неудачная попытка логина на такую систему занимает на полсекунды дольше, чем обычно. Андрес Фройнд заметил эти полсекунды задержки. Они его раздражали. Он решил найти, какой новый баг к этому приводит, и нашел эту лазейку.

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

Теперь все думают, что надо было/надо теперь делать по-другому, и как обнаружить следующую лазейку такого типа - или предыдущую, если она уже есть и никто не знает! - не опираясь на удачу и героическую занудливость Андреаса Фройнда.
1🔥6👍3😱3😁1
SSE или стримы на PHP
#пост

SSE – Server-sent events. Стрим – потоковая передача данных в рамках одной сессии.

SSE – протокол общения сервера и клиента, когда сервер отдает информацию частично, при этом не обрывая и не завершая соединение.

Для простой реализации такого протокола потребуется:

- Добавить в HTTP Headers Content-Type: text/event-stream
- В HTTP Body писать следующее:
- Передача сообщения начинается с data:
- Заканчивается сообщение с \n\n на конце строки
- Таких сообщений может быть неограниченное количество
- Задержка между сообщения может быть любая: секунда, минута, 30 минут, прочее

Рассмотрим несколько примеров с возможностями SSE:

- Так пишутся комментарии, с двоеточием вначале


: comment
: another comment
data: ...


- Кастомное имя события. Если не указать event, то событие будет типа message. В моем примере тип события = question с телом в виде JSON


event: question
data: {"tg_channel":"@handle_topic"}


- Событие с id. Не вижу в этом id какой-то полезности для себя.


data: text message
id: 55


- Длинные строки. Это всё еще одно событие.


data: looooooooooooooooong text
data: looooooooooooooooong text
data: looooooooooooooooong text


- А это уже два разных сообщения:


data: payload1

data: payload2



- Еще можно указать retry в milliseconds. Будет учтено при обрыве соединения и попытке восстановления. Например, 1 секунда (1000 миллисекунд).


data: ok
retry: 1000


Это довольно удобная штука, когда нужно что-то недолго* постримить пользователю:

- Прогресс бар для загрузки файлов
- Какое-то реалтайм действие
- Асинхронная операция и прочее

Реализация

Реализовать на чистом PHP довольно просто: посмотреть пример можно здесь.

Однако, мало кто пишет на чистом пхп свои бекенды. Скорее всего на бекенде используется какой-то фреймворк с ответами в виде класса Response. Либо сразу в контроллере, либо под капотом происходит трансформация возвращаемого значения в строковый ответ.

Если разбирать PSR ResponseInterface , то HTTP Body формируется через метод withBody, который принимает объект StreamInterface. Ага, вот и стримы обещанные.

Стримы

Так как задать несколько ответов с задержкой?

Раз уж наш ответ является стримом, то стрим не обязан возвращать все данные “за одно чтение”.

Поэтому можно сделать некий буфер, который будет вычитываться в методе read() . Если данных больше не будет, то достаточно поменять флаг eof и вернуть его в соответствующем методе объекта стрима.

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

- Бекенд будет думать, что клиент всё принял и обработал
- Клиент получит часть, что-то сломается, и получить остальную часть он уже не сможет
- Дополнительные затраты на память

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

Ограничения

Разберем еще несколько ограничений SSE:

- Можно стримить только body
- Хедеры нельзя менять после начала стрима
- Кодировка всегда UTF-8

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

Проблемы

- Сложная реализация
- Реализовывать стримминг событий на PHP при помощи SSE еще и в PSR обёртках?
- Проще подключить Mercure и настроить его.
- Протокол – пустышка
- Ни авторизации, ни разделения на каналы, ни бродкастинга
- Всё делать либо в HTTP, либо самому
- По сути в нем можно перегонять лишь текст и всё
- Это как HTTP внутри HTTP. Шутка про монитор в мониторе
- Свободные воркеры
- Свободные воркеры веб-сервера превращаются в зомби за мгновение
- Поэтому таймауты обязательны
- Либо Non-blocking I/O. Кстати, надо бы попробовать.

---

Полезные ссылки:

MDN Server-sent events
StreamInterface
HTML Standard

@handle_topic
1👍8🤨1
#мем

Концовка топ😂
С днем космонавтики!

День космонавтики — отмечаемая сначала в СССР, а после в России и других странах постсоветского пространства 12 апреля дата, установленная в ознаменование первого полёта человека в космос.
1👍7🔥3🍾2
Media is too big
VIEW IN TELEGRAM
С новым годом!

Вчера День Космонавтики, а сегодня Новый Год в Тайланде!

Называется Songcran. Отмечают его несколько дней. В больших туристических местах просто засады с обливанием водой друг друга. У каждого уважающего себя тайца имеется мега водяная пушка. А самых хитрые берут кастрюлю и поливают тебя из ведра, а совсем ниндзя приспускают окно в машине стреляют в тебя 👍

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

На популярных пляжах вроде бы вообще пенные вечеринки на улицах.
Тайцы веселые и добрые. Будьте, как тайцы 😉
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍7🔥3
Регулярные выражения! 👻
Не страшно? И не должно!
#мысли

Пару недель назад решил написать серию статей по регулярным выражениям.
Сел описывать все свои знания. Хотел очень кратко уложиться в 1-2 поста, чтобы захватить минимальный комфортный максимум, чтобы не забивать голову о рекурсиях и прочих вещах, но в то же время суметь написать регулярку для какого-нибудь DSL.

В общем, из 1-2 постов это переросло в 8 и там я еще не уложил реально сложные вещи.

Хотел сделать ежедневную серию, чтобы был какой-то фидбек от вас с решением задачек: от простых к легким. А в конце могли бы подвести итог разбором или созданием своего парсера, например, урезанной версии PHP или Python.

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

На прошедшей недели по работе пришлось сделать пару вещей на регулярках и опять пришел к мысли о написании серии постов.
Однако вчера пришла другая идея: создать отдельный канал а-ля “5min regexp”: раз в какое-то время базово проходиться по базовым и сложным вещам, время от времени публиковать разборы задачек, интерактивы в виде выбора правильного результата и задач на размышление.

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

Что думаете, отдельный канал с интерактивами, задачками, обучалками, разборами или серия больших и жирных постов?
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍12
Куда пропал?
#оффтоп

С середины Апреля ничего не писал, но много разного произошло.
Если перестал писать статьи и заметки, то чем дольше этого не делаешь, тем дольше будешь это откладывать. Кто занимается подобным то скорее всего меня понимает. При этом у меня в черновиках есть несколько "продакшен-реди" статей, даже это откладывалось.
Решил не делать новогодних резолюций, а взять и написать сегодня.

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

Пока готовлю статью для хабра, жду финальных апрувов, надеюсь вам понравится.

Всех с наступающим 🎄❄️☃️
1🔥1563🎄2
Хэндлим тему | Дерепко
Куда пропал? #оффтоп С середины Апреля ничего не писал, но много разного произошло. Если перестал писать статьи и заметки, то чем дольше этого не делаешь, тем дольше будешь это откладывать. Кто занимается подобным то скорее всего меня понимает. При этом…
👍Апрувнули релиз, плагин теперь доступен, статья лежит на хабре, можно пользоваться и хейтить.

Короткий обзор возможностей:
Плагин позволяет сделать строчки чем-то большим, чем просто строковый литерал.

Например, строка может быть:
- Названием файла
- Названием свойства класса
- Названием метода
- Еще что-то?

Плагин имеет некую систему базового референса, от которого можно делать вычисления:
- Проект
- Директория
- Текущий файл
- Переменная ($var->…)
- Аргумент (method($var, …))

Описывая эти вещи самому можно сделать довольно сложные вычисления простым декларативным языком:

Подсказки для Yii2 метода render():

<files
className="\yii\base\Controller"
methodName="render"
argumentIndex="0"
fileExt="php"
relatedTo="file"
>
<directoryProcessors>
<regexp from="Controller\.php" to=""/>
<regexp from="([a-z])([A-Z])" to="$1-$2"/>
<regexp from="/controllers/" to="/views/"/>
<regexp from="/modules/([^\\/]+)/views/" to="/themes/default/modules/$1/views/"/>
</directoryProcessors>
</files>


Подсказка метода render() в файле представления:

<files
className="\yii\base\View"
methodName="render"
argumentIndex="0"
fileExt="php"
relatedTo="directory"
/>


Подсказка мейлера:

<files
className="\yii\swiftmailer\Mailer"
methodName="compose"
argumentIndex="0"
fileExt="php"
relatedTo="project"
>
<directoryProcessors>
<append value="common/mail/" />
</directoryProcessors>
</files>


Подсказка Active Form:

<properties
className="\yii\widgets\ActiveForm"
methodName="field"
argumentIndex="1"
relatedTo="argument"
relatedArgumentIndex="0"
/>


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

——

Статья: https://habr.com/ru/articles/868898

Публичный репозиторий: https://github.com/xepozz/meta-storm-idea-plugin

Плагин на маркетплейсе: https://plugins.jetbrains.com/plugin/26121-meta-storm

@handle_topic
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥16👍1
Всех с наступившим Новым 2️⃣0️⃣2️⃣5️⃣ годом 🎅
В новом году нас с вами ждут много классных проектов, тысячи нереализованных идей, куча статей, сотни крутых материалов для изучения и конечно релиз Yii3!
А плагин MetaStorm уже готов к финальной полировке рефакторинга структуры конфигов, а новые фичи уже просятся в релиз.
Остаемся на связи 👋
Please open Telegram to view this post
VIEW IN TELEGRAM
1🎄643👍3