Backend разработчик
Когда я начинал изучать программирование, передо мной встал классический вопрос: какой язык выбрать? Открыл TIOBE, посмотрел на топ-20… и запутался окончательно. Perl в топ-15? Assembly? Fortran? Когда вы последний раз видел вакансию с требованием Fortran?
Тогда я решил проверить гипотезу: насколько популярные рейтинги технологий соответствуют реальному спросу на рынке труда? Результаты оказались показательными.
Начнём с того, как работает TIOBE. Его методология основана на подсчёте поисковых запросов в различных поисковых системах. Звучит логично, но есть нюанс: поисковый запрос “Python tutorial” может делать как практикующий разработчик, так и студент, выполняющий курсовую работу. Visual Basic держится в топе во многом благодаря тому, что миллионы офисных работников гуглят “как написать макрос в Excel”.
Более того, в топ-20 TIOBE регулярно попадают языки вроде Assembly, Fortran и Ada. Да, эти технологии используются в узкоспециализированных областях (встроенные системы, научные вычисления, аэрокосмическая отрасль), но их доля в общем объёме разработки минимальна.
И самое важное: западные рейтинги полностью игнорируют региональную специфику. Они не учитывают особенности рынка СНГ, где есть свои лидеры и свои тренды.
Я решил построить рейтинг на основе реальных данных о спросе. Для этого был разработан парсер, который собирает данные с платформ по поиску работы, в первую очередь с hh.ru, career.habr.com и других российских площадок.
Что анализируется:
Технические детали:
Для каждой технологии рассчитывается нормализованный индекс популярности на основе количества вакансий. В будущем планируется добавить дополнительные метрики: активность на GitHub (количество репозиториев, stars, commits), обсуждения на Stack Overflow, статистику загрузок пакетов из npm, PyPI, Composer и других репозиториев.
Вот топ языков программирования по количеству вакансий:
Место | Технология | Индекс | Комментарий |
---|---|---|---|
1 | SQL | 47.86 | Ожидаемо: работа с БД требуется практически везде |
2 | Python | 38.00 | Универсальность: от веб-разработки до ML |
3 | 1С | 32.89 | Специфика российского рынка |
4 | C | 26.48 | Системное программирование, embedded |
5 | JavaScript | 25.22 | Веб-разработка, фронтенд и бэкенд |
6 | Java | 21.68 | Enterprise-разработка |
7 | C++ | 20.93 | Высоконагруженные системы, gamedev |
8 | PHP | 18.66 | Веб-разработка |
1С на третьем месте. Это выше JavaScript, Java и C++. В TIOBE этого языка вообще нет, потому что он не используется за пределами СНГ. Но для российского рынка это огромный сегмент: тысячи компаний работают на платформе 1С, и спрос на специалистов стабильно высокий.
PHP держится в топ-10. В TIOBE он на 14-м месте, про него регулярно пишут статьи в духе “PHP умирает”. На практике же PHP находится на 8-м месте по количеству вакансий. Причина проста: существует огромное количество работающих проектов на PHP, они требуют поддержки и развития. Это классический пример расхождения между “что популярно в теории” и “что нужно на практике”.
Отсутствие экзотических языков. В топ-20 нет ни Fortran, ни Ada, ни Prolog. Они есть в TIOBE, но реальный спрос на них в разы меньше.
Для начинающих разработчиков: Данные показывают, какие технологии дают больше шансов на трудоустройство. Если выбираете первый язык для изучения, имеет смысл ориентироваться на реальный спрос работодателей.
Для практикующих специалистов: Рейтинг помогает понять, в какую сторону развиваться. Видно, какие технологии набирают популярность, а какие теряют позиции.
Для технических руководителей: При выборе стека для нового проекта важно учитывать не только технические характеристики, но и доступность специалистов на рынке. Данные о количестве вакансий дают объективную картину.
Для HR и рекрутеров: Понимание реального спроса на технологии помогает оценить конкуренцию за специалистов и планировать бюджеты на найм.
Текущая версия использует только данные о вакансиях. В планах добавить:
Все метрики будут нормализованы и объединены в единый индекс с весовыми коэффициентами для каждого параметра.
Актуальный рейтинг доступен на trueindex.ru. Проект обновляется ежемесячно, данные находятся в открытом доступе.
Если интересно обсудить методологию, предложить улучшения или добавить новые технологии в отслеживание – пишите в комментариях или в Telegram @ihxnnxs.
Популярные рейтинги технологий часто оторваны от реальности рынка труда. TIOBE, основанный на поисковых запросах, показывает одну картину, а реальный спрос работодателей – совершенно другую.
Анализ более 150 000 вакансий показал:
Для принятия решений о выборе технологий стоит опираться на данные реального рынка, а не на абстрактные индексы популярности.
P.S. Специально для laravel.su (и, возможно, для других сайтов, посвящённых статьям про PHP). Сам проект реализован на Laravel – если вам интересно, могу написать отдельную статью специально для вас, с конкретным стеком или с рассказом о проблемах и т. п. только дайте знать в комментах :)
Backend, Frontend, Weekend
Работа над проектом на Laravel становится заметно эффективнее, если автоматизировать как можно больше этапов — от конфигурации окружения до проверки кода и тестирования. В этом материале я расскажу, как сделать рабочий процесс надёжным, уменьшить ручную рутину и поддерживать качество кода на высоком уровне.
Материал рассчитан на тех, кто уже знаком с Laravel и хочет внедрить в проект автоматические проверки, единый стиль кода, статику и готовую Docker-инфраструктуру. Я поделюсь используемыми инструментами, примерами конфигураций и реалистичными скриптами.
Я всегда начинаю проект с продуманной конфигурации Docker Compose — это дает сразу готовое изолированное окружение, минимизирует конфликты зависимостей и ускоряет старт работы. Обычно в моём составе используются следующие сервисы:
services:
app:
build: .
container_name: pet
user: root
depends_on:
- pgdb
- redis
- loki
env_file:
- .env
working_dir: /var/www/
volumes:
- .:/var/www
networks:
- pet
dns:
- 8.8.8.8
- 1.1.1.1
pgdb:
container_name: pgdb
image: postgres
tty: true
restart: always
environment:
- POSTGRES_DB=${DB_DATABASE}
- POSTGRES_USER=${DB_USERNAME}
- POSTGRES_PASSWORD=${DB_PASSWORD}
ports:
- ${PGDB_PORT}
volumes:
- ./docker/postgres:/var/lib/postgresql/data
networks:
- pet
nginx:
image: nginx:latest
container_name: nginx
restart: unless-stopped
ports:
- ${NGINX_PORT}
- "443:443"
volumes:
- .:/var/www
- ./docker/nginx:/etc/nginx/conf.d
- /etc/letsencrypt:/etc/letsencrypt:ro
environment:
- TZ=${SYSTEM_TIMEZONE}
depends_on:
- pgdb
- app
- pgadmin
networks:
- pet
pgadmin:
image: dpage/pgadmin4:latest
restart: always
depends_on:
- pgdb
environment:
- PGADMIN_DEFAULT_EMAIL=${PGADMIN_EMAIL}
- PGADMIN_DEFAULT_PASSWORD=${PGADMIN_PASSWORD}
ports:
- ${PGADMIN_PORT}
networks:
- pet
redis:
image: redis:latest
container_name: redis
restart: always
ports:
- ${REDIS_PORT}
environment:
- REDIS_PASSWORD=${REDIS_PASSWORD}
command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}"]
networks:
- pet
redisinsight:
image: redislabs/redisinsight:latest
container_name: redisinsight
ports:
- ${REDISINSIGHT_PORT}
volumes:
- ./docker/redisinsight:/db
restart: always
networks:
- pet
grafana:
image: grafana/grafana:latest
container_name: grafana
user: "472"
ports:
- ${GRAFANA_PORT}
environment:
- GF_SECURITY_ADMIN_USER=${GRAFANA_USER}
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
volumes:
- ./docker/grafana:/var/lib/grafana
depends_on:
- loki
networks:
- pet
queue:
build: .
image: docker_template:latest
container_name: laravel_queue
restart: always
depends_on:
- app
- redis
env_file:
- .env
working_dir: /var/www
volumes:
- .:/var/www
command: php artisan queue:work --sleep=3 --tries=3 --timeout=90
networks:
- pet
dns:
- 8.8.8.8
- 1.1.1.1
loki:
image: grafana/loki:latest
container_name: loki
ports:
- ${LOKI_PORT}
networks:
- pet
volumes:
pgdata:
networks:
pet:
driver: bridge
Каждый из этих сервисов разворачивается в отдельном контейнере. Такой подход даёт преимущества:
Совет: можно использовать готовый шаблон docker-compose.yml, который сразу поднимает все сервисы и настраивает базовые параметры Laravel.
Для автоматического форматирования и приведения к единому стилю я использую laravel/pint. Он позволяет:
Пример конфигурации pint.json
:
{
"preset": "psr12",
"exclude": [
"vendor",
"storage",
"node_modules",
"bootstrap/cache"
],
"rules": {
"array_syntax": {
"syntax": "short"
},
"binary_operator_spaces": {
"default": "single_space"
},
"braces": true,
"class_attributes_separation": {
"elements": {
"const": "one",
"method": "one",
"property": "one"
}
},
"no_unused_imports": true,
"ordered_imports": true,
"phpdoc_separation": true,
"phpdoc_align": true,
"single_quote": true,
"ternary_to_null_coalescing": true,
"trailing_comma_in_multiline": {
"after_heredoc": true
},
"types_spaces": {
"space": "none"
},
"phpdoc_no_empty_return": false,
"no_superfluous_phpdoc_tags": false,
"concat_space": {
"spacing": "one"
}
}
}
Такая конфигурация помогает стандартизировать стиль: синтаксис массивов, расположение операторов, форматирование импортов и PHPDoc.
Запуск Pint перед коммитом — хорошая практика, она поддерживает чистоту кода автоматически.
Чтобы ловить ошибки и потенциальные проблемы ещё на этапе разработки, я применяю комбинацию phpstan/phpstan и nunomaduro/larastan. Эти инструменты позволяют:
Пример конфигурации phpstan.neon
:
parameters:
level: 6
paths:
- app
- routes
excludePaths:
- vendor
- storage
- bootstrap
errorFormat: table
checkMissingVarTagTypehint: false
inferPrivatePropertyTypeFromConstructor: true
ignoreErrors:
- identifier: missingType.iterableValue
- identifier: missingType.generics
- '#referenced with incorrect case#'
includes:
- vendor/phpstan/phpstan/conf/bleedingEdge.neon
Основные преимущества такого подхода:
Чтобы гарантировать, что все коммиты соответствуют стандартам, я применяю Git Hooks + shell-скрипты:
Pre-commit: проверка изменённых файлов обрабатываются только изменённые файлы (для скорости); запускаются Pint и PHPStan на этих файлах; при ошибках коммит блокируется до исправления.
Постепенное исправление старых ошибок особенно полезно на существующих проектах: допускаются коммиты, если количество ошибок в файле уменьшилось; таким образом проверка внедряется постепенно, без резкого прерывания работы команды.
Проверка наличия тестов
Скрипт проверяет, что для любого нового или изменённого класса создан соответствующий тест в директории tests. Например, если добавлен класс app/Services/UserService.php
, ожидается файл tests/Unit/Services/UserServiceTest.php
.
Проверка сборки Docker Отдельный скрипт останавливает текущие контейнеры, пересобирает стек и проверяет, что все сервисы поднялись корректно. Это позволяет убедиться, что изменения в конфигурации или коде не сломали окружение.
Скрипт для проверки с PHPStan (pre-commit / push)
#!/bin/bash
COMMAND="$1" # commit или push
if [ "$COMMAND" = "commit" ]; then
NEW_FILES=$(git diff --cached --name-only --diff-filter=A | grep '\.php$')
if [ -n "$NEW_FILES" ]; then
vendor/bin/phpstan analyse --no-progress --error-format=table $NEW_FILES || exit 1
fi
fi
BASELINE_FILE=".phpstan-error-count.json"
[ ! -f "$BASELINE_FILE" ] && echo "{}" > "$BASELINE_FILE"
if [ "$COMMAND" = "commit" ]; then
ALL_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.php$' || true)
elif [ "$COMMAND" = "push" ]; then
BRANCH=$(git rev-parse --abbrev-ref HEAD)
ALL_FILES=$(git diff --name-only origin/$BRANCH --diff-filter=ACM | grep '\.php$' || true)
fi
if [ -n "$ALL_FILES" ]; then
for FILE in $ALL_FILES; do
ERR_NEW=$(vendor/bin/phpstan analyse --error-format=raw --no-progress "$FILE" 2>/dev/null | grep -c '^')
ERR_OLD=$(jq -r --arg file "$FILE" '.[$file] // empty' "$BASELINE_FILE")
[ -z "$ERR_OLD" ] && ERR_OLD=$ERR_NEW
TARGET=$((ERR_OLD - 1))
[ "$TARGET" -lt 0 ] && TARGET=0
if [ "$ERR_NEW" -le "$TARGET" ]; then
jq --arg file "$FILE" --argjson errors "$ERR_NEW" '.[$file] = $errors' "$BASELINE_FILE" > tmp && mv tmp "$BASELINE_FILE"
else
echo "Ошибка статического анализа в $FILE: $ERR_NEW (допустимо ≤ $TARGET)"
vendor/bin/phpstan analyse --error-format=table "$FILE"
exit 1
fi
done
fi
exit 0
Скрипт для проверки Pint стиля
#!/bin/bash
COMMAND="$1"
if [ "$COMMAND" = "commit" ]; then
ALL_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.php$' || true)
elif [ "$COMMAND" = "push" ]; then
BRANCH=$(git rev-parse --abbrev-ref HEAD)
ALL_FILES=$(git diff --name-only origin/$BRANCH --diff-filter=ACM | grep '\.php$' || true)
fi
if [ -n "$ALL_FILES" ]; then
vendor/bin/pint --test $ALL_FILES
if [ $? -ne 0 ]; then
vendor/bin/pint $ALL_FILES
echo "$ALL_FILES" | xargs git add
exit 1
fi
fi
exit 0
Проверка наличия тестов для классов
Для достижения этой цели я использую скрипт, который проверяет наличие тестов для каждого PHP-класса, добавленного или изменённого в коммите.
Скрипт получает список изменённых и добавленных PHP-файлов и ищет соответствующий тестовый файл в директории tests.
Например, если в проекте есть класс app/Services/UserService.php, скрипт потребует создать файл теста tests/Unit/Services/UserServiceTest.php. Таким образом, любой новый или изменённый класс обязательно должен иметь соответствующий тест, что помогает поддерживать качество и надёжность кода.
Это скрипт, который постоянно дополняется, поэтому актуальную версию вы можете посмотреть здесь – https://github.com/prog-time/git-hooks
Проверка работы Docker сборки
Не менее важно регулярно проверять работу Docker сборки. Для этого я создаю отдельный shell-скрипт, который перезапускает все контейнеры и проверяет, что они успешно запустились. Такой подход позволяет убедиться, что изменения в конфигурации или коде не нарушили работу сервисов и приложение корректно поднимается в локальной среде.
Скрипт может автоматически останавливать текущие контейнеры, заново собирать их и запускать в фоне. После запуска выполняется проверка состояния через docker ps
или docker compose ps
, чтобы убедиться, что все контейнеры находятся в статусе healthy или up.
#!/bin/bash
echo "=== Остановка всех контейнеров ==="
docker-compose down
echo "=== Сборка контейнеров ==="
docker-compose build
echo "=== Запуск контейнеров в фоне ==="
docker-compose up -d
# Пауза для запуска сервисов
echo "=== Ждем 5 секунд для старта сервисов ==="
sleep 5
echo "=== Проверка состояния контейнеров ==="
# Получаем статус всех контейнеров
STATUS=$(docker-compose ps --services --filter "status=running")
if [ -z "$STATUS" ]; then
echo "Ошибка: ни один контейнер не запущен!"
exit 1
else
echo "Запущенные контейнеры:"
docker-compose ps
fi
# Дополнительно можно проверять HEALTHCHECK каждого контейнера
echo "=== Проверка состояния HEALTH ==="
docker ps --filter "health=unhealthy" --format "table {{.Names}}\t{{.Status}}"
echo "=== Скрипт завершен ==="
exit 0
Автоматизация разработки в Laravel — не просто модный тренд, а способ сделать вашу команду эффективнее, а проект — надежнее.
Основные принципы:
Если вы внедрите эти практики, вы:
Автоматизируйте рутинные задачи — и команда сможет сфокусироваться на настоящей ценности: создании функционала и развитии продукта.
Backend разработчик
Привет!
Меня всегда бесило в веб-разработке то, что каждый новый проект — это создание компонентов с нуля. Кнопочка, инпут, модалка, уведомления… И так бесконечно.
После очередного проекта, где я в тысячный раз писал <button class="px-4 py-2 bg-neutral-500...">
, понял — хватит! Пора сделать что-то, что избавит меня (и вас) от этой рутины.
Так родился UmbraUI — мой первый пакет в принципе и по совместительству пакет UI компонентов для Laravel.
Просто устал каждый раз гуглить “accessibility для чекбоксов” и “почему у меня модалка не закрывается по Escape”…
Хотелось сделать библиотеку, которую я сам буду использовать в своих проектах. Без десятка зависимостей, без необходимости изучать новый фреймворк. Просто — поставил, написал <x-button>
, и оно работает как надо.
Никакого раздувания. Взял самые ходовые компоненты из своих проектов и сделал их нормально. Кнопки, формы, карточки, табы — то, что используешь в 90% случаев.
Всё на Tailwind CSS, вдохновлялся shadcn/ui и другими крутыми библиотеками. Но адаптировал под реалии Laravel-разработки.
Никаких дополнительных зависимостей, сложных сборок или конфликтов. Чистые Blade компоненты, которые работают как родные Laravel элементы.
Потому что в 2025 году не поддерживать dark mode — это как не поддерживать мобильные устройства.
20+ компонентов, которые покрывают 95% потребностей:
Формы: Button, Input, Textarea, Select, Checkbox, Radio, Switch, Slider, Date Picker, Label, Field (с валидацией) и т. п.
UI элементы: Alert, Badge, Avatar, Card, Tabs, Accordion, Modal, Dropdown, Link и т. п.
Специальное: Table (с сортировкой), Toast (система уведомлений), Progress
Иконки: 5000 кастомизируемых иконок от Tabler icons
composer require ihxnnxs/umbra-ui
Для JS-функций (toast’ы и т. д.):
php artisan vendor:publish --tag=umbra-ui-assets
Сейчас пакет в активной разработке, но уже вполне рабочий. Планирую добавить:
А самое главное — после стабильного релиза перепишу свои сайты на UmbraUI. Я считаю, что это будет лучшей проверкой того, насколько пакет действительно удобен в реальной работе. Если я сам не буду им пользоваться — значит, что-то делаю не так.
Пакет на GitHub: https://github.com/ihxnnxs/UmbraUI
Если пакет зайдёт — ставьте звёздочку на GitHub ⭐ Это реально мотивирует продолжать развитие проекта.
{message}