Eloquent ORM Code Hinting in PhpStorm

后端 未结 6 1535
再見小時候
再見小時候 2020-12-08 00:57

So I\'m just starting off with Laravel (using v5) and Eloquent. I\'m working on getting some basic APIs up and running and noticing that a lot of working methods don\'t show

相关标签:
6条回答
  • 2020-12-08 01:14

    If you're using BarryVHD's Laravel IDE Helper package, run:

    php artisan ide-helper:eloquent
    

    This will write /** @mixin \Eloquent */ into the vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php file.

    0 讨论(0)
  • 2020-12-08 01:16

    You can try Laravel plug-in for PhpStorm and you need to specifically activate it in your project settings.

    0 讨论(0)
  • 2020-12-08 01:16

    I wanted to have some kind of explicit "casting" when interacting with the query builder. Example...

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

    Since all my models are extending my custom base Model which in turn extends Eloquent, I've ended up creating this method in my custom base model:

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

    This way, it solves the IDE invalid error and helps me:

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

    Please note that this is not OOP type casting. It is only a hint to help the IDE. In my example, the returned Model was already a User. If I woud use this method on a derived class like SuperUser, only the IDE will be fooled...

    An nice alternative also is to put meta information directly over the assignment statement:

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

    Or next to it...

    $user = User::query()->findOrFail($id); /** @var User $user */
    $user->myUserSpecialMethod(); // <-- all OK !
    
    0 讨论(0)
  • 2020-12-08 01:29

    A little late but I recently had the same problem so I thought I would put a note down:

    This is because Database\Eloquent\Model.php has a query() function which returns \Illuminate\Database\Eloquent\Builder and the Eloquent\Builder has a line:

    use Illuminate\Database\Query\Builder as QueryBuilder;
    

    Then it uses 'magic' __call methods to call to functions in Query\Builder. (look for __call method in Eloquent\Builder)

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

    __call() is triggered when invoking inaccessible methods in an object context.

    So, indeed the method you are calling is inaccessible :) There is not much that the IDE can do.

    There are workarounds like using @method tags but it is unmaintainable. An alternative is to use @mixin (but this is not standards based). See: https://github.com/laravel/framework/issues/7558

    I think this all be resolved when they get rid of all the magic calls in the Laravel code and use PHP 'traits' instead. See last message here. :)

    0 讨论(0)
  • 2020-12-08 01:30

    Add in model PHPDoc@mixin

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

    In PHPStorm works

    Or add to \Illuminate\Database\Eloquent\Model

    PHPDoc

    /**
      * @mixin \Eloquent
      */
    abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializable, QueueableEntity, UrlRoutable
    ...
    
    0 讨论(0)
  • 2020-12-08 01:33

    For future Googlers, and perhaps OP as well if you are still sticking to Laravel.

    The laravel-ide-helper package solves this issue for you quite elegantly, with what I believe is a relatively new feature; generated model PHPDocs.

    You can generate a separate file for all PHPDocs with this command:

    php artisan ide-helper:models
    

    The generated metadata will look something like this for each class:

    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 {}
    }
    

    This caused issues for me in PHPStorm however, where the software was complaining about multiple class definitions. Luckily an option is readily available for writing directly to the model files:

    php artisan ide-helper:models -W
    

    There are a few more options and settings available if you need to tweak the behavior, but this is the gist of it.

    0 讨论(0)
提交回复
热议问题