【问题标题】:Eloquent ORM Code Hinting in PhpStormPhpStorm 中雄辩的 ORM 代码提示
【发布时间】:2015-06-08 23:45:48
【问题描述】:

所以我刚开始使用 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,它极大地帮助了将代码提示引入外墙,但对模型/构建者却没有。

有没有人可以解决这个问题?

【问题讨论】:

  • 您是否设置了项目范围(在 phpstorm 中)?
  • @Kyslik 你能澄清一下你的意思吗?项目的设置就像我做过的任何其他项目一样(在涉足 Laravel 之前,我们主要使用 Silex)。其他一切都正常工作,只是模型和构建器上的这几项不正常。
  • @JoshJanusch 我也遇到了同样的问题,你找到解决办法了吗?
  • @Amitay 不,很遗憾,我没有取得任何进展。我刚刚放弃了,差不多。通过__call() 调用的东西太多。弄清楚 Laravel 中有哪些可用的东西真的很困难,尤其是在文档很差以及 Ottwell 记录方法参数的情况下。
  • @JoshJanusch 在做了更多研究后,我发现这是一个 phpstorm 错误。我检查了他们的最新版本,它仍然有错误。希望他们能尽快修复它...

标签: php laravel eloquent phpstorm


【解决方案1】:

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

【讨论】:

  • 这确实改进了一些东西(路线创建、配置交互、一些额外的外观提示),但不幸的是,它对模型没有帮助。还是)感谢你的建议。这肯定会有所帮助。
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

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

    这是因为Database\Eloquent\Model.php 有一个返回\Illuminate\Database\Eloquent\Builderquery() 函数,而Eloquent\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() 在对象上下文中调用不可访问的方法时触发。

    所以,确实你调用的方法是不可访问的 :) IDE 能做的不多。

    有一些解决方法,比如使用@method 标签,但它是不可维护的。另一种方法是使用@mixin(但这不是基于标准的)。 见:https://github.com/laravel/framework/issues/7558

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

    【讨论】:

      【解决方案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 !
      

      请注意,这不是 OOP 类型转换。这只是帮助 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 中工作

        【讨论】:

        • 这确实是一个不错的解决方案,我认为似乎不需要额外的依赖就可以解决问题。
        • 这应该是最终的解决方案。
        【解决方案6】:

        如果您使用 BarryVHD 的 Laravel IDE Helper 包,请运行:

        php artisan ide-helper:eloquent
        

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

        【讨论】:

          【解决方案7】:

          只需在模型类中导入 Eloquent Builder 并添加 mixin:

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

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

          【讨论】:

            【解决方案8】:

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

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

            【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-06-22
            • 1970-01-01
            • 2015-03-31
            • 2021-09-21
            • 2013-08-19
            • 2017-10-05
            相关资源
            最近更新 更多