Eloquent PhpStorm 中的 ORM 代码提示

Eloquent ORM Code Hinting in 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() 行为正确且没有错误。但是,当我键入 User::query()-> 时,PhpStorm 不会显示 orderBy()(或 take()skip(),我敢肯定还有其他人),并在我实际使用它时发出警告。

我正在使用 Laravel IDE Helper,它极大地帮助了 Facades 的代码提示,但似乎没有 models/builders。

有人对此有解决方案吗?

您可以尝试 Laravel plug-in PhpStorm,您需要在您的项目设置中专门激活它。

对于未来的 Google 员工,如果您仍然坚持 Laravel,也许还有 OP。

laravel-ide-helper 软件包非常优雅地为您解决了这个问题,我认为这是一个相对较新的功能;生成模型 PHPDocs.

您可以使用此命令为所有 PHPDoc 生成一个单独的文件:

php artisan ide-helper:models

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

然而,这在 PHPStorm 中给我带来了问题,软件抱怨多个 class 定义。幸运的是,有一个选项可以直接写入模型文件:

php artisan ide-helper:models -W

如果您需要调整行为,还有一些可用的选项和设置,但这就是它的要点。

有点晚了,但我最近遇到了同样的问题所以我想我会记下来:

这是因为 Database\Eloquent\Model.php 有一个 query() 函数,其中 returns \Illuminate\Database\Eloquent\BuilderEloquent\Builder 有一行:

use Illuminate\Database\Query\Builder as QueryBuilder;

然后使用'magic'__call方法调用Query\Builder中的函数。 (在 Eloquent\Builder 中寻找 __call 方法)

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

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

因此,您调用的方法确实无法访问:) IDE 可以做的事情不多。

有一些变通方法,例如使用@method 标记,但无法维护。另一种方法是使用@mixin(但这不是基于标准的)。 参见:https://github.com/laravel/framework/issues/7558

我认为,当他们摆脱 Laravel 代码中的所有魔术调用并改用 PHP 'traits' 时,这一切都会得到解决。 See last message here.:)

我想在与查询生成器交互时有某种明确的 "casting"。示例...

$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 !

请注意,这不是 OOP 类型转换。这只是一个帮助IDE的提示。在我的示例中,返回的 Model 已经是 User。如果我想在像 SuperUser 这样的派生 class 上使用此方法,只有 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 !

在模型 PHPDoc 中添加@mixin

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

}

PHPStorm 中工作

如果您使用的是 BarryVHD 的 Laravel IDE Helper 软件包,运行:

php artisan ide-helper:eloquent

这会将 /** @mixin \Eloquent */ 写入 vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php 文件。

只需在您的模型中导入 Eloquent Builder class 并添加 mixin:

use Illuminate\Database\Eloquent\Builder;
/** @mixin Builder */

一次覆盖所有模型——将 mixin 添加到 src/Illuminate/Database/Eloquent/Model.php)

已在 Laravel 8 上验证,只需将 @mixin Builder 添加到 Illuminate\Database\Eloquent\Model。php 注释即可解决。

// Illuminate\Database\Eloquent\Model.php
/**
  * @mixin Builder
*/
abstract class Model