Laravel IDE Helper: автодополнение моделей и фасадов в PhpStorm

Laravel IDE Helper: автодополнение моделей и фасадов в PhpStorm
содержание

Введение

Многое в Laravel работает через «магию», которую IDE не видит. Статический вызов фасада на деле уходит в объект из контейнера, свойства модели Eloquent появляются из столбцов таблицы, а метода whereEmail() нет ни в одном файле проекта. В итоге PhpStorm не предлагает Cache::remember(), подсвечивает $user->email как неизвестное свойство и не понимает, какой объект возвращает app('cache').

barryvdh/laravel-ide-helper закрывает этот пробел: он читает код проекта и схему базы данных и генерирует по ним PHPDoc, понятный IDE. Текущая ветка 3.x (на момент написания — v3.7.0) работает на PHP 8.2+ с Laravel 11.15+, 12 и 13. Дальше — шпаргалка по порядку: установка, генерация, автообновление, частые проблемы.

Установка

В работающем приложении пакет не участвует, поэтому его место — в require-dev:

composer require --dev barryvdh/laravel-ide-helper

Сервис-провайдер Laravel найдёт сам через автообнаружение пакетов (package discovery). На продакшен зависимости обычно ставят с --no-dev, так что пакета там не будет — так и задумано.

Ручная регистрация

Бывает, что пакет внесён в extra.laravel.dont-discover в composer.json и автоматически не подключается. Тогда провайдер регистрируют сами — в AppServiceProvider::register(), с проверкой окружения:

<?php

namespace App\Providers;

use Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        // только локально и только если пакет установлен
        if ($this->app->isLocal() && class_exists(IdeHelperServiceProvider::class)) {
            $this->app->register(IdeHelperServiceProvider::class);
        }
    }
}

Дописать класс в массив providers в config/app.php, как советуют старые инструкции, не получится: в Laravel 11+ этого массива по умолчанию нет. Добавить провайдер в bootstrap/providers.php можно, но смысла мало. Ошибки при --no-dev не будет, Laravel просто пропустит отсутствующий класс, однако там, где пакет установлен, провайдер загрузится безусловно — в любом окружении. Весь смысл ручной регистрации в проверке окружения, а написать её можно только в коде.

Три команды и когда их запускать

Команда Что генерирует Когда запускать
php artisan ide-helper:generate _ide_helper.php — методы фасадов, макросы, базовый класс \Eloquent после установки и обновления пакетов, после добавления макросов
php artisan ide-helper:models PHPDoc для моделей: свойства, связи, where*, скоупы после миграций и изменения моделей
php artisan ide-helper:meta .phpstorm.meta.php — типы для app('cache'), resolve(), App::make() после установки и обновления пакетов

PHPDoc моделей ссылается на класс \Eloquent, а объявлен он в _ide_helper.php. Если начать с ide-helper:models, методы Query Builder у моделей не появятся, поэтому сначала выполняют ide-helper:generate. Когда полный файл фасадов не нужен, хватит флага -E (--write-eloquent-helper) у ide-helper:models: он записывает минимальную версию файла.

Со своими макросами есть нюанс: в _ide_helper.php они попадают, только если у замыкания указаны типы:

// в AppServiceProvider::boot()
Str::macro('orderNumber', function (int $id): string {
    return 'ORD-' . str_pad((string) $id, 6, '0', STR_PAD_LEFT);
});

Стоит перегенерировать _ide_helper.php, и Str::orderNumber() появляется в подсказках PhpStorm вместе с сигнатурой int $id.

PHPDoc для моделей: куда писать

Типы свойств ide-helper:models берёт из схемы таблиц, так что без доступной БД и выполненных миграций результата не будет. Если запустить команду без флагов, она спросит, куда сохранять PHPDoc. Выбор такой:

Флаг Что происходит Минус
-N, --nowrite всё пишется в _ide_helper_models.php, модели не меняются в проекте два класса App\Models\User, PhpStorm предупреждает о дублях
-W, --write PHPDoc пишется прямо в файл модели при повторном запуске добавляются только новые свойства, изменённые не обновляются
-W -R (--reset) существующий PHPDoc модели заменяется целиком ручные комментарии в PHPDoc теряются
-M, --write-mixin в модель добавляется только @mixin IdeHelperUser, остальное — в _ide_helper_models.php модель всё-таки меняется на три строки

В PhpStorm лучше всего показывает себя -M. Модель почти не меняется, дублей класса нет, а повторный запуск не добавляет @mixin второй раз. К -W -R имеет смысл перейти, если свойства модели должны быть видны прямо в её коде, например на код-ревью. Перед первым запуском с -W или -M модели лучше закоммитить, чтобы изменения было легко просмотреть и откатить.

php artisan ide-helper:models -M

Над атрибутами класса в модели добавляется короткий PHPDoc с одной аннотацией:

/**
 * @mixin IdeHelperUser
 */
#[Fillable(['name', 'email', 'password'])]
#[Hidden(['password', 'remember_token'])]
class User extends Authenticatable

Всё остальное — свойства, счётчики связей, where* и фабрика — уходит в _ide_helper_models.php. Для User из нового проекта на Laravel 13 это выглядит так (с сокращениями):

/**
 * @property int $id
 * @property string $name
 * @property string $email
 * @property \Illuminate\Support\Carbon|null $email_verified_at
 * @property string|null $remember_token
 * @property-read int|null $notifications_count
 * @method static \Database\Factories\UserFactory factory($count = null, $state = [])
 * @method static \Illuminate\Database\Eloquent\Builder<static>|User query()
 * @method static \Illuminate\Database\Eloquent\Builder<static>|User whereEmail($value)
 * @method static \Illuminate\Database\Eloquent\Builder<static>|User whereName($value)
 * @mixin \Eloquent
 */
class IdeHelperUser {}

Автообновление

В README пакета советуют повесить команды на post-update-cmd. В таком виде это работает до первого composer update --no-dev. Пакет из require-dev удаляется, artisan уже не знает команд ide-helper:*, и Composer падает с There are no commands defined in the "ide-helper" namespace и кодом выхода 1. Обычный деплой через composer install --no-dev по lock-файлу не пострадает: post-update-cmd при установке не вызывается.

Обойти ловушку помогает переменная COMPOSER_DEV_MODE — при --no-dev Composer ставит её в 0, и по ней можно пропустить вызов:

"scripts": {
    "post-update-cmd": [
        "@php artisan vendor:publish --tag=laravel-assets --ansi --force",
        "[ \"$COMPOSER_DEV_MODE\" = \"0\" ] || php artisan ide-helper:generate",
        "[ \"$COMPOSER_DEV_MODE\" = \"0\" ] || php artisan ide-helper:meta"
    ],
    "ide-helper": [
        "@php artisan ide-helper:generate",
        "@php artisan ide-helper:meta",
        "@php artisan ide-helper:models -M"
    ]
}

Условие в квадратных скобках рассчитано на POSIX-оболочку, то есть на Linux, macOS, WSL и Docker/Sail. На Windows без WSL надёжнее убрать эти строки из post-update-cmd и запускать composer ide-helper руками — скрипт из того же примера генерирует всё разом.

PHPDoc моделей устаревает после каждой миграции. Чтобы обновлять его автоматически, в опубликованном конфиге предусмотрен массив post_migrate: перечисленные в нём команды запускаются, когда миграции завершены:

// config/ide-helper.php
'post_migrate' => [
    'ide-helper:models -M',
],

Что коммитить

_ide_helper.php и .phpstorm.meta.php строятся из содержимого vendor и весят немало: в чистом Laravel 13 — примерно 950 КБ и 160 КБ. Любой разработчик получает их одной командой, поэтому оба файла обычно отправляют в .gitignore.

С _ide_helper_models.php решение зависит от выбранного режима. Если в моделях есть @mixin, файл лучше коммитить: иначе в свежем клоне модели будут ссылаться на классы IdeHelper*, которых нет. Если же моделей генерация не касается (-N), файл можно игнорировать и генерировать локально.

# .gitignore
_ide_helper.php
.phpstorm.meta.php

Полезные настройки конфига

По умолчанию конфига в проекте нет, его нужно опубликовать:

php artisan vendor:publish --provider="Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider" --tag=config

В config/ide-helper.php на практике меняют немногое:

  • model_locations — где искать модели. По умолчанию ['app'], но можно указать glob-шаблон, например app/Modules/*/Models;
  • write_model_magic_where — нужны ли методы whereEmail() и им подобные для каждого столбца (по умолчанию true). Если такие методы не нужны, опцию выключают — список подсказок станет короче;
  • write_model_relation_count_properties — свойства *_count, которые заполняет withCount() (по умолчанию true);
  • include_fluent — автодополнение цепочек в миграциях вида $table->string('sku')->nullable()->index() (по умолчанию false);
  • post_migrate — команды, которые выполняются после миграций (пример выше).

В старых инструкциях встречается custom_db_types, но в ветке 3.x этой опции нет. Столбцы нестандартных типов описываются как string, а нужный тип задают кастом в модели.

Если подсказок нет

  • Файлы сгенерированы, но PhpStorm их игнорирует. Скорее всего, файл помечен как исключённый (Mark as Excluded) или превышает лимит размера для индексации. Изменения в .phpstorm.meta.php иногда подхватываются только после перезапуска IDE.
  • Команда отработала без ошибок, а свойств у моделей нет. Так бывает, когда БД недоступна: ide-helper:models выводит Could not analyze class App\Models\User, но завершается с кодом 0 и перезаписывает _ide_helper_models.php пустым описанием. Нужно поднять базу, выполнить миграции и повторить генерацию.
  • У части фасадов в _ide_helper.php нет методов. Генератор не смог создать объект за фасадом: обычно мешает ненастроенный драйвер или недоступная база, а причина видна в выводе команды. Драйвер чинят в конфиге, а если фасаду нужна БД, помогает флаг -M (--memory) у ide-helper:generate: он подставляет SQLite в памяти.
  • Не видны новые алиасы из config/app.php. Если конфигурация закеширована (config:cache), генератор читает старую версию. Кеш сбрасывают через php artisan config:clear и генерируют файл заново.
  • IDE ругается на дубли классов моделей. Модели соседствуют с копиями из -N или в них остался старый PHPDoc от -W. Решение — перейти на -M и удалить лишнее.

IDE Helper, Laravel Idea и Larastan

У этих инструментов разные задачи, и друг другу они не мешают. Плагин Laravel Idea разбирается в Eloquent, маршрутах, конфигах и представлениях сам, без сгенерированных файлов, и с июля 2025 года бесплатен для пользователей PhpStorm. Larastan — расширение PHPStan: он ищет ошибки статическим анализом, но автодополнения не даёт. IDE Helper пригодится и рядом с Laravel Idea (скажем, ради макросов), и в VS Code, где такого плагина нет, а PHPDoc, записанный через -W, делает анализ Larastan точнее.

Итог

  • Место пакета — require-dev, провайдер подключается автоматически; если нужна ручная регистрация, её делают в AppServiceProvider с проверкой окружения.
  • Генерация идёт в порядке ide-helper:generate → ide-helper:meta → ide-helper:models -M, причём последней команде нужна рабочая БД.
  • Вызовы в post-update-cmd защищают от --no-dev через COMPOSER_DEV_MODE, а модели обновляются сами через post_migrate.
  • Новый проект удобнее начинать с готовой авторизации: выбор набора описан в статье «Стартовые наборы Laravel 12–13 и laravel/ui», а IDE Helper ставится сразу после него.
  • Следующий инструмент, который стоит поставить в каждый проект, — Laravel Debugbar.

Похожие