Красноречивый код ORM, указывающий в PhpStorm

Итак, я только начинаю с Laravel (используя v5) и Eloquent. Я работаю над запуском некоторых основных API-интерфейсов и замечаю, что многие методы работы не отображаются в подсказке кода PhpStorm

Итак, у меня есть эта модель:

namespace Project\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

class User extends Model 
    implements AuthenticatableContract, CanResetPasswordContract {
}

И в одном из моих контроллеров я пытаюсь сделать

User::query()->orderBy('id', 'desc');

User::query() создает объект Eloquent Builder и orderBy() ведет себя корректно и без ошибок. Тем не менее, PhpStorm не показывает orderBy() (или take(), skip(), и я уверен, что другие), когда я набираю User::query()-> и дает предупреждения, когда я действительно его использую.

Я использую Laravel IDE Helper, который очень помог принести подсказки кода на фасады, но не для моделей/строителей, которые, казалось бы, выглядели бы.

Есть ли у кого-нибудь решение?

Ответ 1

Для будущих гуглеров и, возможно, OP, если вы все еще придерживаетесь Laravel.

Пакет laravel-ide-helper решает эту проблему для вас довольно элегантно, и я считаю, что это относительно новая функция; созданная модель PHPDocs.

Вы можете создать отдельный файл для всех PHPDocs с помощью этой команды:

php artisan ide-helper:models

Сгенерированные метаданные будут выглядеть примерно так для каждого класса:

namespace App {
/**
 * App\Post
 *
 * @property integer $id
 * @property integer $author_id
 * @property string $title
 * @property string $text
 * @property \Carbon\Carbon $created_at
 * @property \Carbon\Carbon $updated_at
 * @property-read \User $author
 * @property-read \Illuminate\Database\Eloquent\Collection|\Comment[] $comments
 */
class Post {}
}

Это вызвало проблемы для меня в PHPStorm, однако, когда программное обеспечение жаловалось на несколько определений классов. К счастью, опция доступна для непосредственного написания файлов модели:

php artisan ide-helper:models -W

Имеется несколько дополнительных параметров и настроек, если вам нужно настроить поведение, но это его суть.

Ответ 2

Вы можете попробовать плагин Laravel для PhpStorm, и вам нужно специально активировать его в настройках вашего проекта.

Ответ 3

Немного поздно, но у меня недавно была такая же проблема, поэтому я подумал, что буду записывать заметку:

Это потому, что Database\Eloquent\Model.php имеет функцию query(), которая возвращает \Illuminate\Database\Eloquent\Builder, а Eloquent\Builder имеет строку:

use Illuminate\Database\Query\Builder as QueryBuilder;

Затем он использует методы "magic" __call для вызова функций в Query\Builder. (найдите __call метод в Eloquent\Builder)

См: http://php.net/manual/en/language.oop5.overloading.php#object.call

__ вызов() запускается при вызове недоступных методов в контексте объекта.

Итак, действительно, метод, который вы вызываете, недоступен:) Существует не так много, что может сделать IDE.

Есть обходные пути, такие как использование тегов @method, но это невозможно. Альтернативой является использование @mixin (но это не стандарт). См.: https://github.com/laravel/framework/issues/7558

Я думаю, что все это будет разрешено, когда они избавятся от всех магических вызовов в коде Laravel и вместо этого используют "черты" PHP. Посмотреть последнее сообщение здесь:)

Ответ 4

Я хотел бы иметь какое-то явное "кастинг" при взаимодействии с построителем запросов. Пример...

$user = User::query()->findOrFail($id);
$user->myUserSpecialMethod(); // <-- IDE syntax error

Поскольку все мои модели расширяют мою пользовательскую базовую модель, которая, в свою очередь, расширяет Eloquent, я создал этот метод в своей пользовательской базовой модели:

/**
 * Explicit type-hinting
 *
 * @return static
 */
static public function hint(BaseModel $model)
{
    return $model;
}

Таким образом, он разрешает неверную ошибку IDE и помогает мне:

$user = User::hint(User::query()->findOrFail($id));
$user->myUserSpecialMethod(); // <-- all OK !

Обратите внимание, что это не кастинг типа ООП. Это только подсказка, чтобы помочь IDE. В моем примере возвращаемый Model уже был User. Если я буду использовать этот метод для производного класса, такого как SuperUser, только IDE будет обмануто...

Хорошей альтернативой также является метаданные непосредственно над оператором присваивания:

/** @var User $user */
$user = User::query()->findOrFail($id);
$user->myUserSpecialMethod(); // <-- all OK !

Или рядом с ним...

$user = User::query()->findOrFail($id); /** @var User $user */
$user->myUserSpecialMethod(); // <-- all OK !

Ответ 5

Добавить в модель PHPDoc @mixin

/**
 * Class News
 * @property int $id
 * @property string $created_at
 * @property string $updated_at
 * @mixin \Eloquent
 * @package App
 */
class News extends Model
{

}

В PHPStorm работает

Или добавить к \Illuminate\Database\Eloquent\Model

PHPDoc

/**
  * @mixin \Eloquent
  */
abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializable, QueueableEntity, UrlRoutable
...