pkg-cache — простой локальный кеш пакетов

Пример реализации простого кэширующего прокси для пакетов npm, composer и pip на базе node.js для Windows и Linux.

Скриптовый язык общего назначения

Пример реализации простого кэширующего прокси для пакетов npm, composer и pip на базе node.js для Windows и Linux.

Большинство ORM строятся вокруг естественного предположения: одной таблице соответствует одна entity. Это настолько привычно, что даже не обращаешь внимания.
Это не правило, но вокруг него проектируются почти все остальные механизмы: метаданные принадлежат классу, Unit of Work отслеживает экземпляры этого класса, миграции собираются из его описания, а объектная модель постепенно начинает повторять структуру базы данных.
Но часто в коде не требуется вся таблица, многие поля служат только конкретным процессам и ни читать, ни менять эти поля в других процессах не требуется. В статье посмотрим два подхода работы с сущностями. А также к чему я пришёл, попробовав сделать по‑другому.

Именно так я думал, когда начинал разбираться в этой теме. Но, разобравшись, я с уверенностью могу сказать, что это реально, такая идея имеет место быть и обслуживать такую архитектуру легко.
В данной статье будет описан процесс реализации архитектуры веб‑приложения с удобной системой докер контейнеров. Здесь не будет обсуждаться CI/CD, исключительно development‑side процесса разработки.
Я использую самый свежий на момент написания PHPStorm 2026.1.4 от Jetbrains, но абсолютно не важно какой IDE вы пользуетесь. В теории можно и в блокноте писать хороший код.

На примере PHP хорошо видно, как внутренние оптимизации динамически типизированного языка развиваются и усложняются.
PHP‑массив выглядит универсальным, но внутри него скрыто множество оптимизаций и ветвлений, в их числе оптимизации для хранения и работы с массивами: Packed List & HashTable. Взаимодействие между ними и copy‑on‑write дают иногда неожиданное и непрозрачное поведение с точки зрения PHP программиста.

16 лет назад я написал на Хабре статью «Нетрадиционные животные в доме» – про то, каких экзотов держат дома и с какими проблемами сталкиваются их владельцы. Статья неожиданно собрала довольно живые комментарии и подняла мне карму.
С тех пор мало что поменялось, разе что оборудование, корма, террариумы и животных стало проще находить, в остальном же всё осталось по-прежнему. Есть старые форумы и разрозненные группы во «ВКонтакте». Есть несколько сайтов, часть из которых давно заброшена. Но нет места, где можно собрать «коллекцию» своих животных, вести журнал наблюдений, найти пару для разведения, составить вишлист и просто быть среди своих.
Прошло 16 лет. Проект, наконец, дозрел.

Кто хотя бы раз работал в вебстудии над создаваемыми сайтами, знает, что используемые там универсальные движки очень даже норовистые. Чуть не уследил за правильной кастомизацией кода под требования клиента - на получи тормоза при открытии его страниц.
И ведь не сразу найдёшь, где же в глубинах проекта образовался проблемный фрагмент, начавший поглощать ресурсы сайта.
Для поиска таких мест были созданы разные инструменты профилирования. Этим термином называют всестороннее измерение нагрузки, оказываемой исследуемым скриптом на сервер сайта. Например, для языка PHP наиболее известными профилировщиками кода являются следующие: Blackfire, Xdebug Profiler, Tideways, XHProf/XGHui.
Но что если вам важнее не разноплановый функционал популярных инструментов, сколько возможность в один щелчок побыстрее выполнить основную функцию: замерить нагрузку сразу по всем задействованным файлам CMS и понятно визуализировать результат.
Для решения подобной узкой задачи я разработал очень простой бесплатный профилировщик PHP. Так сказать, студийную версию профайлера, то есть урезанную до объёма, достаточного вебмастеру при работе над проектами в студии. И делюсь этим скриптом с сообществом. Кому интересно, прошу под кат.

Классический мониторинг отвечает на вопрос «открылась ли страница». Магазин со сломанным приёмом заказов отвечает на него уверенное «да»: витрина рендерится, корзина считает, 200 OK, сертификат валиден. Не работает только одно — деньги не проходят. Шлюз остался в тест-режиме после работ, обновление сломало оформление, растёт доля сорвавшихся оплат — снаружи всё зелёное.
Разбираем, как проверять приём заказов изнутри WooCommerce: три сигнала из статистики заказов с порогами, нормированными на собственную норму магазина (чтобы не будить владельца двух заказов в неделю), и суточный smoke-прогон конвейера заказа — создать скрытый виртуальный товар, провести заказ по статусам, удалить всё за собой. Без единого письма, без следов в отчётности, без реальных платежей.
Плюс две грабли, на которых мы посидели: письма WooCommerce не глушатся фильтром woocommerce_email_classes (к моменту cron хуки уже развешаны на init — бить надо в woocommerce_email_enabled_{id}), а finally не спасает от PHP-фатала, из-за чего в чужом магазине остаётся висеть служебный заказ. И почему headless-браузер — это отдельный уровень, а не замена этому.

Полгода назад я начал писать пет-проект практически полностью с помощью LLM-агентов. Первые недели это был чистый дофамин: фичи вылетали за вечер, я один успевал столько, сколько раньше делала небольшая команда. А потом всё начало вязнуть — ровно так, как вязнет любой проект с говнокодом: каждая новая фича ломала две старые, агент правил код «на ощупь», а я тратил время не на продукт, а на разгребание.
Под катом — что я понял и что в итоге сработало: почему LLM деградирует на плохой архитектуре точно так же, как команда людей; почему SOLID, DDD и чистая архитектура не устарели, а стали важнее; и как превратить архитектурные договорённости из «пожеланий в CLAUDE.md» в контракт, который машина не может нарушить. С конкретикой: два конфига deptrac для Symfony-бэкенда и пайплайн разработки с субагентом-ревьювером.

Представьте, что Вам вообще можно не думать, что сегодня съесть. Интереснее каждый день удивляться чему-то, а не иметь готовое меню на каждый день, но для этого сначала нужно четко понимать, что ты ешь сегодня, а что - завтра.
Я поразмыслил над тем, как сделать современную электронную книгу рецептов, и на выходе получил проект умного холодильника, где на каждый день задаешь меню, а программа сама считает пищевую ценность, содержание полезных веществ, анализирует, насколько питание полноценное и сбалансированное. Таким образом, можно быстро создавать себе меню на неделю, которое может оказаться идеальным для продуктивности в Ваших физических тренеровках. Но далее открывается вообще новый мир: автоматизация покупки продуктов, четкое понимание, что нужно взять в магазине, ясный взгляд, сколько раз стоит питаться, чтобы не было дефицита белка или витаминов, где стоит использовать БАД и так далее. Аппаратная часть – матовый сенсорный дисплей на магнитах, подключенный к старому относительно бесполезному до этого проекта ноутбуку.

Два года по вечерам в одиночку пилю текстовую MMORPG в Telegram. Сейчас в ней 1111 аккаунтов и 586 выживших, которые бродят по мрачному острову. И где-то в админке ждёт кнопка, которая сотрёт их прогресс до нуля. Сезонный вайп, как в Rust. Я собрал её, проверил на тестовом сервере и до сих пор не нажал на проде. Рассказываю, почему «стереть всех» это не DELETE FROM, как один разработчик не держит в голове 99 таблиц, и какой тест блокирует мне деплой, если я забыл про новую таблицу.
Ниже речь пойдет о том, как спроектировать и реализовать довольно гибкую систему авторизации для вашего проекта.
Для начала неплохо было бы зафиксировать понятия. Далее по тексту под авторизацией понимается процесс проверки прав субъекта на доступ к определенному ресурсу, в том числе на совершение определенных действий, например, по модификации ресурса.
Ресурс - любой объект, служба, данные или программный компонент, доступ к которым его владелец хочет ограничить.
Субъект или актор - конкретный пользователь или система, который хочет получить доступ к ресурсу.
После того, как мы определились с ключевыми понятиями, можно приступить к проектированию системы.
Как следует из заголовка статьи авторизация будет проходить на основе политик, а значит будет логично описать интерфейс этой самой политики, но перед этим необходимо понять, что и как политика будет принимать и какой результат возвращать.

Стандартный обмен данными в 1С-Битрикс часто превращается в ночной кошмар: полная выгрузка остатков на больших каталогах может занимать от 1 до 8 часов. Когда бизнес требует обновлять данные каждые 15 минут, штатные методы API и XML-импорт просто перестают справляться.
В этой статье я покажу, как с помощью прямого SQL запроса и временных таблиц в памяти (ENGINE=MEMORY) ускорить импорт в сотни раз. Это реальный кейс с продакшена, который стабильно работает уже 4 года на проекте с миллионом товаров и десятками складов.

Как работает ядро Joomla 6 на уровне Приложения (Application)? Сколько видов Приложений на самом деле есть в Joomla и в чём между ними разница? Какой жизненный цикл каждого Приложения Joomla, включая роутинг, диспетчеризацию и события плагинов? На эти и другие вопросы попытается дать ответ эта статья, опирающаяся на кодовую базу Joomla 6.1.0. Также в статье хронология вызова триггеров плагинов в разных сценариях.
👉 Бонус для любопытных читателей: а вы знали, что Joomla можно использовать в качестве daemon-процесса?

Я аналитик, а не разработчик. Весь код для созданной нами платформы написал Claude Opus через Claude Code. Рассказываю без хайпа: как выглядит реальный workflow, где нейросеть незаменима, где она бесполезна, и какая инженерная дисциплина обязательна, чтобы это не превратилось в тыкву на боевом.
Сразу обозначу рамку, чтобы снять половину вопросов из комментариев.
Я не умею писать продакшн‑код. Я аналитик: читаю код, рассуждаю о системах, проектирую поведение — но профессионально не кодю. Тем не менее у нас в проде работает нетривиальное веб‑приложение, и каждую строчку кода написала нейросеть (Claude Opus, агент Claude Code). Моя роль — архитектор, продакт и QA. Второй ключевой специалист по разработке — дизайнер вебинтерфейсов, также освоивший Claude.
Это не пост «ИИ сам всё сделал, программисты не нужны». Скорее наоборот: я хочу показать, что инженерия никуда не делась — просто из неё вынули операцию «набирать код руками». Всё остальное (проектирование, компромиссы, ловля прод‑онли багов, дисциплина релизов) осталось на человеке. И вот об этом «остальном» — интереснее всего.

Обычно процесс разработки API выглядит так: мы пишем контроллер. Затем каким-то образом его документируем. После чего фронтер, опираясь на такую документацию, пишет клиент.
Мы делаем одну и ту же работу трижды.
В прошлой статье я рассказывал, как избавиться от первого дублирования. С помощью бандла sunrise-studio/symfony-openapi можно генерировать OpenAPI-документ из кода, минуя процесс документирования.
Но это решает проблему только наполовину. Если OpenAPI-документ вытекает из кода, то клиент должен вытекать из OpenAPI-документа. Иначе написание клиента – и есть то самое дублирование.
В этой статье я расскажу как замкнуть цепочку:
Controller → OpenAPI → Client → Feature
Где каждый последующий шаг вытекает из предыдущего, а не дублирует его.

Для успешной разработки программного обеспечения важны разумное ограничение затрат времени и выбор способов решения задачи. Как я обнаружил, в PHP-фреймворках много такого, что нужно не во всех приложениях. Из-за этого вес пакета и число файлов, упоминаемых в одном логе становится неудобно большим. При этом, число пакетов, используемых под капотом при выполнении базовых действий невелико.
В какой-то момент я понял, что моё дальнейшее развитие как разработчика требует уменьшения затрат времени на треть. Поисковик, генерирующий ответ, увеличивает её не более чем на четверть, и то в основном за счёт чтения документации. Логично взять и соединить всё лучшее от современных технологий и подходов, проверенных временем. Быстро обнаружил, что регулярно не укладываюсь по времени на целые проценты нужного срока. Само собой разумеется проанализировал то, что мешает писать качественный код быстрее. Обнаружил, что фреймворк вообще и реализации отдельных паттернов проектирования в частности, загромождены. Не все очень длинные классы имеют одну ответственность. Нередко в одной сущности объединена функциональность, нужная по отдельности и занимающая много места в коде и в уме.
Сразу замечу, что писать длинные классы не всегда неприемлемо. В любом принципе помимо общего правила есть исключения. Класс с одной ответственностью может содержать большое количество строк кода. Вот только должен поддерживать быструю настройку описанной в нём функциональности. Качественно другая функциональность должна добавляться не путём изменения существующей, а путём создания отдельного модуля. Быстрота понимания разработчиком сложной логики гарантирует выявление подходящего способа решения задачи за разумный срок. Поэтому, я решил написать новый фреймворк с минимальной необходимой функциональностью.

Переход к микросервисной архитектуре неизбежно поднимает вопрос эффективности межсервисного взаимодействия. В PHP традиционный стек на базе PHP-FPM и REST API создает дополнительные накладные расходы: каждый запрос обрабатывается в отдельном процессе, что требует повторной инициализации контейнера зависимостей, загрузки конфигурации и всего контекста приложения. В результате увеличивается latency и снижается пропускная способность сервиса.
В этой статье мы шаг за шагом разработаем высокопроизводительный микросервис на Symfony 7, используя RoadRunner в качестве постоянного приложения-сервера, gRPC для межсервисного взаимодействия и Protocol Buffers для сериализации данных. По итогам вы получите полностью рабочий сервис и поймете, как построить производительную альтернативу классическому стеку PHP-FPM + REST.

В одной из предыдущих статей я поднимал вопрос о том, что интерфейс системы целиком и полностью работает на Английском языке. Я пообещал, что в будущем реализую поддержку нескольких языков, и вот этот момент настал. Но, как это часто бывает, пока я копался в коде ради мультиязычности, попутно переписал пару системных модулей, чтобы они наконец-то работали стабильно ну и не ручками же вводить переменные в файл пакета. Поэтому релиз 3.6.6 получился тройным: Системные исправления, исправления интерфейса ну и новый плагин.

"Если вашего бизнеса нет в Интернете, то вас нет в бизнесе! Скоро на рынке останется два вида компаний: те, кто в Интернете и те, кто вышел из бизнеса."
А потом вдруг интернета не стало и нужно было срочно что-то придумать для работы нашей ERP-системы оффлайн

Привет, Хабр! Меня зовут Леонид, я ведущий PHP-разработчик в НЛМК ИТ.Наша команда отвечает за сервисы HR-направления на едином корпоративном портале (далее – ЕКП), а также занимается развитием и поддержкой корпоративных сайтов.
В предыдущей статье мой коллега рассказывал про подход к использованию гридов на крупном корпоративном портале. Со временем, помимо возможности работать с данными непосредственно на ЕКП, у бизнеса появилась другая потребность – выгружать эти данные в файлы.
В одних сервисах эта потребность была обусловлена необходимостью импорта данных в другую корпоративную систему, в других – необходимостью работы с табличными процессорами и несколькими отчетами одновременно. Соответственно, перед командой встает задача – реализовать механизм выгрузки данных из грида в файловый отчет.