Как настроить PHPStan и Larastan для проверки кода в 2026

Я обычно ставлю PHPStan и Larastan сразу после того, как проект начинает «расти» и в коде уже появляются десятки сервисов, десятки моделей и пара-тройка старых костылей. На PHP 8.1, 8.2 и 8.3 это особенно полезно: часть проблем перестаёт прятаться за фаталами и вылезает раньше — на этапе анализа кода. И это очень хорошо, потому что ловить ошибку в CI дешевле, чем потом разгребать её на проде.

Зачем нужен PHPStan и Larastan в 2026 году

Если говорить по делу, PHPStan — это статический анализатор PHP-кода. Он не запускает приложение, не ходит в базу, не дергает API, а смотрит на код и ищет логические и типовые проблемы. Larastan — это надстройка для Laravel, которая понимает специфику фреймворка: Eloquent, контейнер, фасады, магические свойства моделей, scope-методы и всё вот это добро. Грубо говоря, PHPStan без Larastan в Laravel-проекте работает, но многое просто не понимает.

На моей практике PHPStan чаще всего спасает от очень приземлённых ошибок: передали строку туда, где ожидается int; забыли проверить null; перепутали коллекцию и массив; вызвали метод на переменной не того типа. Звучит банально, но именно такие вещи потом вылезают в самых неудобных местах. У одного клиента после обновления проекта на Laravel 10 и PHP 8.2 анализ нашёл больше 180 проблем, из них примерно 40 были реально опасными. И это был не «грязный» проект, а вполне живой магазин с интеграцией CRM и доставок. После фиксов код стал заметно спокойнее, а количество мелких инцидентов упало.

Честно говоря, я отношу PHPStan к тем инструментам, которые не дают мгновенного вау-эффекта, но очень хорошо окупаются через 2–3 месяца. Особенно если у вас команда, где код пишет не только один человек. И особенно если проект давно живёт без нормальной типизации. Тут уже без статического анализа начинается технический долг, а потом и технический долг сайта растёт как на дрожжах.

ℹ️
Инфо: PHPStan отлично подходит и для поддержки старых проектов, и для новых. Но максимальный эффект он даёт там, где есть CI/CD, нормальные тесты и хотя бы минимальная дисциплина по типам.

Если у вас Laravel-проект на PHP 8.3 и MySQL 8.0, то PHPStan уже не «дополнительная проверка», а почти обязательная часть процесса. А если это Bitrix, WordPress или самописка на Laravel — настраивать качество кода стоит сразу, а не после первой серьёзной поломки. Если нужен не просто анализ, а полноценная доработка сайта под задачу с наведением порядка в коде, я обычно советую начинать именно с проверки и инвентаризации ошибок.

Какие версии брать в 2026 году

Я бы не советовал ставить всё подряд «посвежее, потому что свежее». На деле лучше смотреть на совместимость проекта. В 2026 году для большинства проектов рабочая зона такая: PHP 8.2 и 8.3 — самый комфортный выбор, PHP 8.4 уже нормален для новых проектов, но старые пакеты иногда упираются в несовместимости. Если у вас Laravel 10 или Laravel 11, то PHPStan и Larastan ставятся без сюрпризов, но зависимости нужно проверять внимательно. Иногда один устаревший пакет ломает половину анализа.

Для Laravel я обычно ориентируюсь на актуальную связку:

Если проект старый, на Laravel 8 или 9, иногда лучше не гнаться за самым последним Larastan. Иначе вы получите пачку ложных срабатываний и пару вечеров, потраченных впустую. Это плохая идея. Я лучше потрачу время на аккуратную настройку baseline и постепенное повышение уровня, чем на героическую борьбу с инструментом, который сам по себе начинает мешать.

⚠️
Не делайте так: не ставьте «максимальный уровень» PHPStan в первый же день на большой проект. Если у вас 5–10 тысяч строк legacy-кода, вы получите сотни ошибок и просто перестанете смотреть на отчёт.

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

Установка PHPStan и Larastan через Composer

Обычно я ставлю анализаторы через dev-зависимости, чтобы они не попадали в production. Это стандартная и правильная история. На Laravel-проекте команда примерно такая:

composer require --dev phpstan/phpstan nunomaduro/larastan

Если у вас в проекте уже есть пакет PHPStan extensions или какие-то дополнительные правила, их тоже можно подключить сразу. Но я советую не начинать с зоопарка. Сначала базовая связка, потом уже добираем расширения. Иначе вы не поймёте, какой пакет даёт ошибку и где именно конфликт.

После установки я обычно создаю файл конфигурации phpstan.neon в корне проекта. Для Laravel у Larastan есть свои рекомендации, и базовая конфигурация может выглядеть так:

includes:
    - vendor/nunomaduro/larastan/extension.neon

parameters:
    level: 5
    paths:
        - app
        - config
        - database
        - routes
    tmpDir: storage/phpstan
    checkMissingIterableValueType: true
    checkGenericClassInNonGenericObjectType: false
    treatPhpDocTypesAsCertain: false
    inferPrivatePropertyTypeFromConstructor: true
    ignoreErrors:
        - '#Unsafe usage of new static#'

Я специально показал не «идеальную» конфигурацию, а реальную стартовую. На практике я почти всегда начинаю с level 4–6, а не с 9. Для legacy-проекта это нормально. Потом, когда проект очищается, можно поднимать уровень до 7, 8 и выше. Но делать это надо поэтапно.

💡
Совет: храните tmpDir в storage/phpstan или в отдельной временной папке проекта. На больших кодовых базах это ускоряет повторные проверки, особенно в CI на PHP 8.3.

Если вам надо не просто внедрить анализатор, а ещё и понять, что в проекте уже сломано, я бы параллельно заказал проверку сайта. Иногда ошибки в коде идут рука об руку с проблемами производительности, 500-ми ошибками и странными регрессиями после деплоя.

Настройка PHPStan для Laravel-проекта

Larastan хорош тем, что он умеет «видеть» Laravel-магии больше, чем обычный PHPStan. Но даже с ним проект нужно немного дисциплинировать. Я обычно первым делом проверяю, как настроены namespace’ы, автозагрузка Composer и структура папок. Если проект собран кое-как, анализатор будет ругаться не только по делу, но и на то, что команда просто привыкла делать руками.

В Laravel очень часто встречаются магические вызовы через фасады и Eloquent. Например, User::where(...)->first() или config('app.name'). Larastan это понимает, но только если проект не сломан в базовых вещах. У меня был случай, когда после переезда на новый хостинг и обновления до PHP 8.2 проект начал вести себя нормально только внешне. PHPStan сразу показал, что несколько репозиториев возвращают не те типы, а один сервис вообще иногда отдаёт array|false, хотя в коде везде ожидался массив. Это была настоящая скрытая проблема, которая могла выстрелить в редких сценариях.

Хороший приём — добавлять строгие PHPDoc-аннотации там, где нет полноценной типизации. Например:

<?php

namespace App\Services;

use App\Models\Order;
use Illuminate\Support\Collection;

/**
 * @param Collection<int, Order> $orders
 * @return array<int, int>
 */
public function calculateTotals(Collection $orders): array
{
    $result = [];

    foreach ($orders as $order) {
        $result[] = (int) $order->total;
    }

    return $result;
}

Да, это не самый «красивый» код с точки зрения пуристов. Но на деле именно такие аннотации часто снимают половину предупреждений. И да, PHPStan любит типы. Чем точнее вы их зададите, тем меньше шума будет в отчёте.

Ещё один важный момент — работа с коллекциями, mixed-типами и nullable-значениями. Если в проекте много mixed, анализ будет слабым. Я обычно советую постепенно вытеснять mixed из сервисного слоя. Не сразу, а по частям. Иначе проект превратится в болото, где один сервис не понимает другой.

Baseline или чистая обезопасенная настройка

С baseline я сталкиваюсь постоянно. И честно говоря, это нормальный инструмент, если вы наследуете большой проект. Baseline позволяет зафиксировать текущие ошибки, чтобы новые изменения проверялись строго. Это не магия и не «обман анализатора». Это способ не утонуть в старом коде и при этом не терять контроль над новым.

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

vendor/bin/phpstan analyse --generate-baseline

После этого в конфиге появляется отдельный файл baseline, который содержит список уже известных проблем. Я чаще всего храню его отдельно и пересобираю только после крупных правок. Но тут есть нюанс: если baseline живёт годами, он начинает скрывать реальный технический мусор. Это уже не помощь, а костыль.

⚠️
Осторожно: baseline нельзя превращать в свалку. Если он перестал уменьшаться, значит команда перестала чистить код. Это уже тревожный сигнал.

На моей практике лучший подход — baseline + правило «новые ошибки не проходят». То есть старые проблемы можно гасить постепенно, а новые коммиты должны быть чистыми. Это почти всегда работает лучше, чем пытаться сразу привести всё к уровню 9. Если нужен такой же системный подход не только к коду, но и к поддержке проекта в целом, иногда помогает регулярная настройка силами специалиста с ревизией архитектуры и наследия.

PHPStan в CI/CD и на сервере

Сам по себе анализатор на локальной машине — это хорошо, но пользы в разы больше, если он встроен в CI. У меня обычно проверка запускается на каждом pull request или merge request. И это правильно, потому что ошибку надо останавливать до попадания в main или production.

Пример для GitHub Actions выглядит примерно так:

name: PHPStan

on:
  pull_request:
  push:
    branches:
      - main

jobs:
  analyse:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.3'
          extensions: mbstring, intl, pdo_mysql
          tools: composer:v2

      - name: Install dependencies
        run: composer install --no-interaction --prefer-dist --no-progress

      - name: Run PHPStan
        run: vendor/bin/phpstan analyse --memory-limit=1G

Я обычно ставлю память не меньше 1G, а на крупных проектах — 2G. Особенно если это Laravel-монолит с десятками сервисов, очередями и большим количеством моделей. Иначе анализатор может упереться в лимит и начать падать не по делу. На PHP 8.3 с Composer 2.7 и нормальным хостингом это работает вполне стабильно.

Если CI у вас ещё не выстроен, то сначала лучше поправить базовую инфраструктуру. Серьёзно. Анализ кода без нормального процесса деплоя — это половина дела. Я бы в таком случае параллельно посмотрел и на настройку окружения разработчика: Docker, Git, CI/CD, и на версионирование и откат обновлений сайта. Эти вещи очень хорошо работают в паре.

Для серверной части я нередко советую запускать анализ в staging-среде. Особенно если у проекта есть отдельный поддомен для тестов. Это безопаснее, чем гонять всё на боевом сервере. И если у вас уже настроен staging-сайт, полезно свериться со статьёй как настроить staging-сайт для безопасной проверки обновлений.

Как сделать анализ быстрым и без лишнего шума

Одна из частых жалоб: «PHPStan слишком медленный» или «он ругается на ерунду». На деле чаще всего проблема не в инструменте, а в конфиге. Если вы сразу анализируете всё подряд — vendor, cache, generated classes, временные файлы — будет медленно и грязно. Поэтому я всегда ограничиваю пути и исключаю мусор.

Вот что я обычно делаю:

Если проект очень большой, я иногда делаю несколько конфигураций: одну для приложения, вторую для тестов, третью для доменного слоя. Это удобно, когда кодовая база действительно разрастается. Не всем это надо, но в проектах на 100–200 тысяч строк это уже спасает.

Для ускорения помогает и нормальный серверный стек. На практике PHPStan быстрее работает на PHP 8.2/8.3, чем на старых версиях, особенно если включён OPcache и сервер не задыхается от плохой конфигурации. Если хостинг слабый, анализ будет тормозить вдвое сильнее. И тут уже возникает вопрос не только к коду, но и к инфраструктуре. Иногда нужна не только проверка кода, но и общая проверка сайта, потому что проблемы расползаются по всему стеку.

Типичные ошибки и как их исправить

Самые частые ошибки, которые я вижу после первого запуска PHPStan, обычно однотипные. Где-то возвращается mixed, где-то забыли тип параметра, где-то метод обещает array, а фактически возвращает null. Ещё очень часто всплывают неинициализированные свойства, лишние условия и вызовы несуществующих методов на Eloquent-моделях.

Например, такой код PHPStan не любит:

<?php

public function showUser(array $data)
{
    if ($data['user']) {
        return $data['user']->name;
    }

    return null;
}

Здесь сразу несколько проблем: нет типизации результата, нет проверки существования ключа, и непонятно, что вообще лежит в $data['user']. Нормальная версия выглядит так:

<?php

/**
 * @param array{user?: \App\Models\User|null} $data
 */
public function showUser(array $data): ?string
{
    $user = $data['user'] ?? null;

    if ($user === null) {
        return null;
    }

    return $user->name;
}

И вот после таких правок качество кода резко растёт. Да, это чуть дольше на этапе разработки. Но зато потом меньше багов, меньше регрессий и меньше ночных «срочно почините, у клиента упало». Я лучше один раз приведу код к типам, чем потом три раза подряд искать одну и ту же проблему.

В Laravel ещё часто всплывают ошибки с коллекциями и Builder-объектами. Если вы вызываете ->first(), а потом думаете, что у вас всегда модель, PHPStan быстро укажет, где именно логика не совпадает с реальностью. Это особенно полезно для бизнес-логики, где ошибка в одном методе может затронуть заказы, оплаты и синхронизацию с CRM. Если тема вам близка, советую посмотреть и статью интеграция CRM с сайтом: как это сделать правильно.

PHPStan и Larastan в работе с командой

Когда я внедряю PHPStan в командный проект, я никогда не делаю это «в лоб». Сначала обсуждаем уровень, правила, baseline и формат отчёта. Потом показываю примеры типичных ошибок. И только потом подключаем проверку к PR. Иначе разработчики начинают воспринимать инструмент как наказание, а это уже путь в никуда.

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

У одного клиента я видел неплохую схему: каждый merge request обязан проходить PHPStan level 6 без новых ошибок, а раз в две недели команда выделяет час на уменьшение baseline. Сначала казалось, что это лишняя бюрократия. Через три месяца они сами признали, что код стал стабильнее, а ревью — короче. Потому что часть глупых вопросов просто перестала возникать.

ℹ️
Подсказка: если команда большая, добавьте короткий внутренний гайд: что делать при ошибке PHPStan, как писать PHPDoc, когда использовать nullable-типы и как не злоупотреблять ignoreErrors.

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

Итоговая схема настройки для Laravel-проекта

Если собрать всё в рабочую схему, я бы делал так. Сначала проверил версию PHP и зависимости. Для 2026 года комфортная база — PHP 8.2 или 8.3, Laravel 10/11, Composer 2.7+. Потом ставим PHPStan и Larastan через dev-зависимости. Затем создаём конфиг, стартуем с level 5–6, подключаем Laravel extension и смотрим на отчёт. После этого генерируем baseline, если проект старый, и постепенно уменьшаем его.

Дальше подключаем анализ в CI, чтобы новые ошибки не попадали в main. Потом правим самые болезненные места: mixed-типы, nullable, неверные возвраты, магические вызовы, неявные коллекции. И уже после этого поднимаем уровень на одну ступень выше. Я обычно советую делать это раз в 1–2 недели, а не раз в полгода. Так процесс идёт без истерики.

Если проект связан с бизнесом, интернет-магазином, CRM или внутренними кабинетами, PHPStan и Larastan однозначно стоит внедрять. Это не модная игрушка. Это нормальный способ снизить количество багов, особенно когда код пишут несколько человек. А если вам нужно не просто поставить анализатор, а привести проект в порядок, можно посмотреть и на услуги вроде калькулятор стоимости сайта — там проще прикинуть бюджет на доработки и поддержку.

На моей практике после внедрения PHPStan в Laravel-проектах реже ломаются интеграции, быстрее проходит ревью и проще обновляться между версиями PHP. И да, в 2026 году это уже не «желательно», а почти базовая гигиена кода. Особенно если у вас не один разработчик, а команда. Особенно если проект живой. Особенно если вы не хотите каждые пару месяцев ловить неожиданные 500-е ошибки или странные регрессии после обновления.

Хотите настроить PHPStan и Larastan без лишних ошибок?

Следуйте пошаговой инструкции, чтобы внедрить статический анализ в Laravel-проект и повысить качество кода в 2026 году.

П
Павел
Веб-разработчик · 10+ лет опыта · Bitrix, WordPress, Laravel

Читайте также

Что такое SSL-сертификат и зачем он нужен сайту Защита API-ключей на сайте: настройка и хранение 2026 Бэкапы сайта: как делать правильно и не терять данные