🧩 Один разработчик, 10 лет, ввой PHP-фреймворк
На Хабре вышла статья про LOTIS (Low Time Script) — фреймворк, который автор в одиночку допиливал десять лет под бизнес-приложения (учёт товаров, документы, расчёт зарплат, прибыли).
Идея у него радикальная: никаких шаблонов и разметки. Всё веб-приложение собирается из PHP-объектов, а клиентский и серверный код живут рядом, как в десктопе.
В основе принцип, который автор назвал CMA: Construct → Metadata → Assembly:
→ объекты реализуют общий интерфейс Construct;
→ они генерируют метаданные;
→ а класс Space уже собирает из них DOM, реактивность или API.
То есть ты описываешь не <div>, а объект предметной области. И пока не отдашь его «во вселенную» (LTS::Space()->build(...)) — это просто объект, которому можно менять вложенность простым перераспределением наследования.
Не инструмент «нести в прод завтра», но честная, выстраданная попытка переосмыслить разработку веб-приложений на PHP. Как минимум — хороший повод подумать о метаданных и декларативном UI. Сейчас автор портирует архитектуру на Node.js (PWA, локальные БД, оффлайн).
Любопытно, спорно, авторски. Разбор и куски боевого кода в оригинале
💬 Что думаете?
Библиотека пхпшника
На Хабре вышла статья про LOTIS (Low Time Script) — фреймворк, который автор в одиночку допиливал десять лет под бизнес-приложения (учёт товаров, документы, расчёт зарплат, прибыли).
Идея у него радикальная: никаких шаблонов и разметки. Всё веб-приложение собирается из PHP-объектов, а клиентский и серверный код живут рядом, как в десктопе.
В основе принцип, который автор назвал CMA: Construct → Metadata → Assembly:
→ объекты реализуют общий интерфейс Construct;
→ они генерируют метаданные;
→ а класс Space уже собирает из них DOM, реактивность или API.
То есть ты описываешь не <div>, а объект предметной области. И пока не отдашь его «во вселенную» (LTS::Space()->build(...)) — это просто объект, которому можно менять вложенность простым перераспределением наследования.
Не инструмент «нести в прод завтра», но честная, выстраданная попытка переосмыслить разработку веб-приложений на PHP. Как минимум — хороший повод подумать о метаданных и декларативном UI. Сейчас автор портирует архитектуру на Node.js (PWA, локальные БД, оффлайн).
Любопытно, спорно, авторски. Разбор и куски боевого кода в оригинале
Библиотека пхпшника
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥3🤔3👏1😁1
🔥 Инженерная методичка по ИИ от Романа Барлоса (Team Lead в Yandex Cloud)
Продолжаем делиться экспертизой команды курса «Разработка ИИ-агентов».
Роман собрал мастхев-инструменты и ключевые работы для тех, кто хочет выйти за рамки вайбкодинга.
🛠️ Полезные инструменты:
📚 Ключевые работы по LLM:
На курсе Роман выступает консультантом программы: помогает формировать содержание уроков с опорой на актуальные инженерные практики».
Занять свое место на потоке:
👉 Курс «Разработка ИИ-агентов»
Продолжаем делиться экспертизой команды курса «Разработка ИИ-агентов».
Роман собрал мастхев-инструменты и ключевые работы для тех, кто хочет выйти за рамки вайбкодинга.
🛠️ Полезные инструменты:
• Understand Anything — граф знаний по коду и зависимостям.
• DeepTutor — open-source платформа для персонализированного обучения.
• Superpowers — набор практик для системной разработки с ИИ.
• Awesome Agent Skills — коллекция навыков для ИИ-агентов.
📚 Ключевые работы по LLM:
• Attention Is All You Need (2017) — архитектура Transformer.
• GPT-1 (2018) — начало эпохи GPT.
• GPT-2 (2019) — решение новых задач без дообучения.
• GPT-3 (2020) — обучение на примерах из запроса.
• InstructGPT (2022) — RLHF и современные чат-боты.
На курсе Роман выступает консультантом программы: помогает формировать содержание уроков с опорой на актуальные инженерные практики».
Занять свое место на потоке:
👉 Курс «Разработка ИИ-агентов»
🥱2
⚡️ Работаем с curl
Нужно скачать файл и продолжить загрузку после обрыва? curl -C - автоматически продолжит с того места, где остановился — не нужно качать заново.
🔹 Зачем это нужно
— Загрузка больших файлов через нестабильное соединение.
— Автоматически определяет размер уже скачанной части и продолжает.
— Работает с HTTP, FTP и даже SFTP.
🔹 Как использовать
— Скачать с возможностью продолжения:
— С прогресс-баром:
— Ограничить скорость:
— В конкретный файл:
— С авторизацией:
💡 Заверни в цикл для автоматического ретрая:
Нужно скачать файл и продолжить загрузку после обрыва? curl -C - автоматически продолжит с того места, где остановился — не нужно качать заново.
🔹 Зачем это нужно
— Загрузка больших файлов через нестабильное соединение.
— Автоматически определяет размер уже скачанной части и продолжает.
— Работает с HTTP, FTP и даже SFTP.
🔹 Как использовать
— Скачать с возможностью продолжения:
curl -C - -O https://example.com/dump.sql.gz— С прогресс-баром:
curl -C - -# -O https://example.com/large-file.tar.gz— Ограничить скорость:
curl --limit-rate 10M -O https://example.com/file.iso— В конкретный файл:
curl -C - -o backup.tar.gz https://example.com/backup— С авторизацией:
curl -C - -u user:pass -O https://repo.example.com/artifact.jarwhile ! curl -C - -O https://example.com/dump.sql.gz; do sleep 5; done — скрипт будет пытаться докачать, пока не получится.Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤1🔥1
🔍 Repr: var_dump для людей
Когда в логи надо вывалить значение неизвестного типа, начинается зоопарк: var_export ломается на ресурсах, print_r плюётся простынями, json_encode давится бинарными строками. Библиотека icecave/repr делает то, что в Python называется reprlib — короткое и понятное представление чего угодно.
Массивы режутся до 3 элементов и 3 уровней вложенности с подсчётом остатка, строки — до 50 символов с экранированием контрол-кодов, а объекты показывают класс и SPL-хеш (если есть __toString или RepresentableInterface — используется он).
⚙️ Установка: composer require icecave/repr. Инструмент идеально подходит для кастомных эксепшенов и структурного логирования, где var_export выдает нечитаемый ад.
Библиотека пхпшника
Когда в логи надо вывалить значение неизвестного типа, начинается зоопарк: var_export ломается на ресурсах, print_r плюётся простынями, json_encode давится бинарными строками. Библиотека icecave/repr делает то, что в Python называется reprlib — короткое и понятное представление чего угодно.
use Icecave\Repr\Repr;
echo Repr::repr([1, 2, 3]);
// [1, 2, 3]
echo Repr::repr($pdo);
// <PDO #0000000012ab>
echo Repr::repr(fopen('php://memory', 'r+'));
// <resource stream #5 r+>
Массивы режутся до 3 элементов и 3 уровней вложенности с подсчётом остатка, строки — до 50 символов с экранированием контрол-кодов, а объекты показывают класс и SPL-хеш (если есть __toString или RepresentableInterface — используется он).
⚙️ Установка: composer require icecave/repr. Инструмент идеально подходит для кастомных эксепшенов и структурного логирования, где var_export выдает нечитаемый ад.
Библиотека пхпшника
❤4👍1🔥1
🧩 Eloquent-модель, которая знает слишком много
Модель Order ездит по всему приложению: контроллер → Action → Service → Job. И везде тащит не только данные, но и запросы, персистентность, связи, события. Бизнес-логика начинает зависеть от имён колонок (customer_id, total_cents) и может случайно дёрнуть ->delete().
Expressive ставит типизированную границу поверх Eloquent. БД остаётся за Eloquent, а логика работает с чистым типизированным объектом:
Что это даёт:
→ Типы видны в классе. $order->totalCents = '1000' отвергнет сам PHP. Енамы строкой не подсунешь.
→ Fail на границе. null в non-nullable свойстве — NonNullablePropertyException, а не сюрприз тремя методами позже.
→ Без ленивых сюрпризов. Связи мапятся, только если запросил их явно. Не запросил — null.
→ Генератор + sync. make:expressive поднимает класс из модели, expressive:sync ловит дрейф в CI.
Не тащите везде: CRUD живёт на голом Eloquent, для API — по-прежнему API Resources. Expressive — для важных бизнес-флоу, где модель несёт лишнюю ответственность.
🔗 Подробнее
Библиотека пхпшника
Модель Order ездит по всему приложению: контроллер → Action → Service → Job. И везде тащит не только данные, но и запросы, персистентность, связи, события. Бизнес-логика начинает зависеть от имён колонок (customer_id, total_cents) и может случайно дёрнуть ->delete().
Expressive ставит типизированную границу поверх Eloquent. БД остаётся за Eloquent, а логика работает с чистым типизированным объектом:
$order = OrderModel::query()
->findOrFail($id)
->expressive(attributes: ['payable']);
Что это даёт:
→ Типы видны в классе. $order->totalCents = '1000' отвергнет сам PHP. Енамы строкой не подсунешь.
→ Fail на границе. null в non-nullable свойстве — NonNullablePropertyException, а не сюрприз тремя методами позже.
→ Без ленивых сюрпризов. Связи мапятся, только если запросил их явно. Не запросил — null.
→ Генератор + sync. make:expressive поднимает класс из модели, expressive:sync ловит дрейф в CI.
Не тащите везде: CRUD живёт на голом Eloquent, для API — по-прежнему API Resources. Expressive — для важных бизнес-флоу, где модель несёт лишнюю ответственность.
🔗 Подробнее
Библиотека пхпшника
👍5❤2🔥2
Forwarded from Библиотека задач по PHP | тесты, код, задания
Какой тип связи реализуется через промежуточную таблицу?
Anonymous Quiz
3%
hasOne
23%
hasMany
51%
belongsToMany
23%
morphTo
👍5🤔2❤1🔥1
⌨️ Топ-вакансий по PHP за неделю
PHP-разработчик — до 200 000 ₽ — удалёнка
PHP-разработчик — от 200 000 ₽ — гибрид (Москва)
Fullstack разработчик (Laravel + Vue.js/React.js) — от 1600 до 2240 $ — удалёнка
➡️ Еще больше топовых вакансий — в нашем канале PHP Jobs
PHP-разработчик — до 200 000 ₽ — удалёнка
PHP-разработчик — от 200 000 ₽ — гибрид (Москва)
Fullstack разработчик (Laravel + Vue.js/React.js) — от 1600 до 2240 $ — удалёнка
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
🛒 Ecommerce-фреймворк, где ядро можно переопределять, не форкая
Bagisto — open-source ecommerce на Laravel 12 (PHP 8.3+), 27k звёзд.
Но интересен он не «магазином из коробки», а тем, как устроена кодовая база: это не монолит, а 30+ самостоятельных пакетов под Webkul\*, каждый со своими роутами, миграциями, моделями и тестами. Подключаются через Composer path-repositories и обычные сервис-провайдеры.
Каждая модель реализует контракт (интерфейс), а резолвится в рантайме через прокси. На практике это значит, что свой пакет может подменить ядровую модель Product или Order без правки core-файлов и без форка:
Каталог построен на EAV — гибкая схема атрибутов вместо раздувания таблицы товаров. Атрибуты раскладываются по families/groups, а значения пишутся в product_attribute_values, причём тип атрибута маппится на конкретную колонку через $attributeTypeFields (text / boolean / integer / datetime), а не сваливается в один value.
Доступ к данным — через repository pattern на prettus/l5-repository. Базовый Webkul\Core\Eloquent\Repository даёт критерии-фильтры, кэширование и оптимизацию запросов поверх Eloquent:
Из коробки также мультиканальность/мультитенант, POS, headless через Next.js и Flutter-приложение в отдельных репо. Админка на Vue 3.
Хороший кейс, если хочется посмотреть, как держать большой Laravel-проект модульным и расширяемым без боли при апгрейдах.
🔗 Репозиторий на GitHub
🐸 Библиотека пхпшника
Bagisto — open-source ecommerce на Laravel 12 (PHP 8.3+), 27k звёзд.
Но интересен он не «магазином из коробки», а тем, как устроена кодовая база: это не монолит, а 30+ самостоятельных пакетов под Webkul\*, каждый со своими роутами, миграциями, моделями и тестами. Подключаются через Composer path-repositories и обычные сервис-провайдеры.
Каждая модель реализует контракт (интерфейс), а резолвится в рантайме через прокси. На практике это значит, что свой пакет может подменить ядровую модель Product или Order без правки core-файлов и без форка:
// твой ServiceProvider
$this->app->concord->registerModel(
\Webkul\Product\Contracts\Product::class,
\App\Models\CustomProduct::class
);
Каталог построен на EAV — гибкая схема атрибутов вместо раздувания таблицы товаров. Атрибуты раскладываются по families/groups, а значения пишутся в product_attribute_values, причём тип атрибута маппится на конкретную колонку через $attributeTypeFields (text / boolean / integer / datetime), а не сваливается в один value.
Доступ к данным — через repository pattern на prettus/l5-repository. Базовый Webkul\Core\Eloquent\Repository даёт критерии-фильтры, кэширование и оптимизацию запросов поверх Eloquent:
class ReturnRequestRepository extends Repository
{
public function model(): string
{
return 'Webkul\RMA\Contracts\ReturnRequest';
}
}
Из коробки также мультиканальность/мультитенант, POS, headless через Next.js и Flutter-приложение в отдельных репо. Админка на Vue 3.
Хороший кейс, если хочется посмотреть, как держать большой Laravel-проект модульным и расширяемым без боли при апгрейдах.
Please open Telegram to view this post
VIEW IN TELEGRAM
😁5🔥4🥱2👍1
🔥 Строишь ИИ-агентов? Руководитель AI/ML-направления Сloud․ru покажет, где большинство архитектур ломаются, и как этого избежать.
18 июня в 19:00 совместно с Сloud․ru проведём открытый урок «Мультиагентные системы: почему большинство архитектур переусложнены».
Спикер — Дмитрий Юдин, эксперт по масштабированию и оптимизации вычислительных ресурсов для ML. Под его руководством развивается Evolution AI Factory — цифровая среда для работы с GenAI. Он занимается развитием сервисов генеративного ИИ, инфраструктуры для обучения больших языковых моделей и внедрением интеллектуальных агентов.
Что получишь на уроке:
— критерии выбора между одним агентом и мультиагентной системой;
— разбор популярных архитектурных ошибок;
— реальные ограничения современных ИИ-агентов;
— практические рекомендации по проектированию агентных систем.
🎁 Для участников урока подготовили промокод на скидку 10 000 ₽.
🗓️ Когда: 18 июня, 19:00 (МСК)
👉 Занять место на открытом уроке
18 июня в 19:00 совместно с Сloud․ru проведём открытый урок «Мультиагентные системы: почему большинство архитектур переусложнены».
Спикер — Дмитрий Юдин, эксперт по масштабированию и оптимизации вычислительных ресурсов для ML. Под его руководством развивается Evolution AI Factory — цифровая среда для работы с GenAI. Он занимается развитием сервисов генеративного ИИ, инфраструктуры для обучения больших языковых моделей и внедрением интеллектуальных агентов.
Что получишь на уроке:
— критерии выбора между одним агентом и мультиагентной системой;
— разбор популярных архитектурных ошибок;
— реальные ограничения современных ИИ-агентов;
— практические рекомендации по проектированию агентных систем.
🎁 Для участников урока подготовили промокод на скидку 10 000 ₽.
🗓️ Когда: 18 июня, 19:00 (МСК)
👉 Занять место на открытом уроке
💻 3 курса по цене одного — собери стек для оффера в топовую IT-компанию
Для следующего карьерного шага мало писать код. Работодатели ждут не только знания языка, но и понимания архитектуры, алгоритмов, автоматизации, AI-инструментов и агентных систем.
Одно направление закрывает только часть задачи.
Поэтому сейчас мы предлагаем освоить сразу несколько востребованных навыков — выбери любой курс и получи доступ еще к двум бесплатно 🔥
Собери стек навыков под свою цель:
🔹 подготовка к сильным компаниям (алгоритмы, архитектура);
🔹 переход в AI-направление (ИИ-агенты, AgentOps);
🔹 развитие в ML и Data Science (математика, основы ML);
🔹 новый оффер и рост дохода.
Полученные знания применяешь в работе уже во время обучения.
⏳ Акция действует 48 часов — 13 и 14 июня.
👉 Переходи на сайт, выбирай курсы и оставляй заявку — за 10 минут поможем собрать комплект под твою цель.
Для следующего карьерного шага мало писать код. Работодатели ждут не только знания языка, но и понимания архитектуры, алгоритмов, автоматизации, AI-инструментов и агентных систем.
Одно направление закрывает только часть задачи.
Поэтому сейчас мы предлагаем освоить сразу несколько востребованных навыков — выбери любой курс и получи доступ еще к двум бесплатно 🔥
Собери стек навыков под свою цель:
🔹 подготовка к сильным компаниям (алгоритмы, архитектура);
🔹 переход в AI-направление (ИИ-агенты, AgentOps);
🔹 развитие в ML и Data Science (математика, основы ML);
🔹 новый оффер и рост дохода.
Полученные знания применяешь в работе уже во время обучения.
⏳ Акция действует 48 часов — 13 и 14 июня.
👉 Переходи на сайт, выбирай курсы и оставляй заявку — за 10 минут поможем собрать комплект под твою цель.
🥱2
🧵 PHP Fibers вместо ада сериализации
В Manychat жили на curl_multi_exec для псевдоконкурентных запросов. Работало, пока AI-фичи не размножились. Каждый внешний вызов означал: сериализуй состояние бизнес-логики, отдай в очередь, дождись, десериализуй, восстанови контекст. Ревью кода превращались в квест — логика рвалась на куски вокруг async-границ.
Добил их апгрейд Ubuntu: OpenSSL 3.0 со своими мьютексами на обходе хранилища сертификатов выкатил +10% к CPU на ровном месте. Виноваты синхронные вызовы Meta API, т.к. каждый payload открывал новый TCP.
Решение — затащить Fibers поверх существующего event loop на Guzzle. Файбер приостанавливается на внешнем HTTP, воркер берёт следующий payload, при готовности ответа возобновляет нужный файбер с того же места:
🚀 Что получили
Переиспользование одного HTTP/2 соединения на воркер (прощай, рукопожатия);
Асинхронный sleep вместо блокировки всего процесса при ретраях;
Линейный код без знания разработчиком про файбер под капотом.
💣 Расплата → радиус поражения. Раньше фатал клал воркер с одним payload. Теперь в полёте висят пятеро файберов, и OOM убивает всех. Catchable-ошибки переписали так, чтобы валить только свой файбер.
Если бы начинали с нуля, взяли бы Revolt или AMPHP. Но кастомный луп уже был, Fibers легли сверху.
🔗 Читать оригинал
🐸 Библиотека пхпшника
В Manychat жили на curl_multi_exec для псевдоконкурентных запросов. Работало, пока AI-фичи не размножились. Каждый внешний вызов означал: сериализуй состояние бизнес-логики, отдай в очередь, дождись, десериализуй, восстанови контекст. Ревью кода превращались в квест — логика рвалась на куски вокруг async-границ.
Добил их апгрейд Ubuntu: OpenSSL 3.0 со своими мьютексами на обходе хранилища сертификатов выкатил +10% к CPU на ровном месте. Виноваты синхронные вызовы Meta API, т.к. каждый payload открывал новый TCP.
Решение — затащить Fibers поверх существующего event loop на Guzzle. Файбер приостанавливается на внешнем HTTP, воркер берёт следующий payload, при готовности ответа возобновляет нужный файбер с того же места:
$fiber = new Fiber(function() {
echo "Suspending\n";
$last = Fiber::suspend(16);
echo "Resuming with {$last}\n";
});
$last = $fiber->start(); // 16
$fiber->resume(42); // 42🚀 Что получили
Переиспользование одного HTTP/2 соединения на воркер (прощай, рукопожатия);
Асинхронный sleep вместо блокировки всего процесса при ретраях;
Линейный код без знания разработчиком про файбер под капотом.
💣 Расплата → радиус поражения. Раньше фатал клал воркер с одним payload. Теперь в полёте висят пятеро файберов, и OOM убивает всех. Catchable-ошибки переписали так, чтобы валить только свой файбер.
Если бы начинали с нуля, взяли бы Revolt или AMPHP. Но кастомный луп уже был, Fibers легли сверху.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍2🔥1
🎥 До открытого урока — несколько дней. Подготовили небольшую подборку материалов от нашего спикера Дмитрия Юдина.
Дмитрий руководит AI/ML-направлением в Сloud․ru и развивает Evolution AI Factory — среду для работы с GenAI: от инфраструктуры обучения LLM до внедрения интеллектуальных агентов.
С чего начать:
📺 AI-инструменты для разработчиков — как код, автотесты и ассистенты меняют рутину инженера.
📺 AI-эволюция бизнеса в эпоху генеративных моделей — агентные системы в реальных продуктах.
📺 Разработка мертва? — дискуссия о будущем профессии и роли AI в ней.
📖 Применение LLM в бизнесе — статья Дмитрия о практике внедрения и роли облака.
Одна из ключевых тем Дмитрия — практическое применение агентных систем и их ограничения.
Именно об этом — бесплатный урок 18 июня в 19:00: «Мультиагентные системы: почему большинство архитектур переусложнены» 🔥
🎁 Для участников подготовили промокод на скидку 10 000 ₽ на курс «Разработка ИИ-агентов».
👉 Успей занять место на открытом уроке
Дмитрий руководит AI/ML-направлением в Сloud․ru и развивает Evolution AI Factory — среду для работы с GenAI: от инфраструктуры обучения LLM до внедрения интеллектуальных агентов.
С чего начать:
📺 AI-инструменты для разработчиков — как код, автотесты и ассистенты меняют рутину инженера.
📺 AI-эволюция бизнеса в эпоху генеративных моделей — агентные системы в реальных продуктах.
📺 Разработка мертва? — дискуссия о будущем профессии и роли AI в ней.
📖 Применение LLM в бизнесе — статья Дмитрия о практике внедрения и роли облака.
Одна из ключевых тем Дмитрия — практическое применение агентных систем и их ограничения.
Именно об этом — бесплатный урок 18 июня в 19:00: «Мультиагентные системы: почему большинство архитектур переусложнены» 🔥
🎁 Для участников подготовили промокод на скидку 10 000 ₽ на курс «Разработка ИИ-агентов».
👉 Успей занять место на открытом уроке
Логи сервера в plain text, нужно быстро подсчитать количество запросов по HTTP-статусам? awk — ваш Swiss Army Knife для обработки текстовых данных прямо в терминале.
🔹 Зачем это нужно
— Мгновенная агрегация данных из логов без загрузки в БД или Python.
— Работает с любым текстовым форматом.
— Есть на каждом сервере.
🔹 Как использовать
— Подсчёт по статусам (nginx access.log):
awk '{print $9}' access.log | sort | uniq -c | sort -rn— Среднее время ответа:
awk '{sum+=$NF; n++} END {print sum/n}' access.log— Только 5xx ошибки:
awk '$9 ~ /^5/' access.log— Топ-10 IP по количеству запросов:
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10— Вывести конкретные поля:
awk -F',' '{print $1, $3}' data.csvPlease open Telegram to view this post
VIEW IN TELEGRAM
❤2👍2🔥1
⚔️ final по умолчанию
Это дисциплина или недоверие к коллегам, зашитое в код?
final + readonly + strict_types + PHPStan lvl 9 + arch()->preset()->strict(), который роняет CI за один пропущенный final.
Аргументы за: composition over inheritance, никаких fragile base class, инварианты под защитой.
Цена: мок в тесте — упёрся в final. Подправить вендорский класс — форк пакета. readonly DTO — пока не понадобился with().
Граница не в «строго/нестрого», а в дефолте: final по умолчанию с осознанными исключениями, или открыто, а final только на классах с инвариантами?
Где у вас проходит эта линия? 👇
— final/readonly на всё
— дайте просто писать код
Пишите мнение в комментах🍿
Это дисциплина или недоверие к коллегам, зашитое в код?
final + readonly + strict_types + PHPStan lvl 9 + arch()->preset()->strict(), который роняет CI за один пропущенный final.
Аргументы за: composition over inheritance, никаких fragile base class, инварианты под защитой.
Цена: мок в тесте — упёрся в final. Подправить вендорский класс — форк пакета. readonly DTO — пока не понадобился with().
Граница не в «строго/нестрого», а в дефолте: final по умолчанию с осознанными исключениями, или открыто, а final только на классах с инвариантами?
Где у вас проходит эта линия? 👇
— final/readonly на всё
— дайте просто писать код
Пишите мнение в комментах🍿
😁2🤔2👍1
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1🔥1
Forwarded from Библиотека задач по PHP | тесты, код, задания
😁11🥱9❤1👍1