Красноречивый код 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
...