【发布时间】:2021-04-09 13:27:30
【问题描述】:
考虑以下代码:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
/**
* Class MyModel
* @package App\Models
* @mixin Builder
*/
class MyModel extends Model
{
public static function getGreens(): Builder
{
return (new self())->where('color', '=', 'green');
}
}
在return 声明中,PhpStorm (2020.3) 抱怨说:
返回值预计为
'\Illuminate\Database\Eloquent\Builder',返回'MyModel'
并建议:
将返回类型从
'\Illuminate\Database\Eloquent\Builder'更改为'MyModel'
这是非常不正确的(where 方法确实返回了 \Illuminate\Database\Eloquent\Builder 的实例,而 IDE 将返回类型推断为 MyModel 类型)。通过删除返回类型,IDE 发出另一个警告:
缺少函数的返回类型声明
代码可以正常运行,但 IDE 不应报告任何 false 警告!我应该如何避免在 PhpStorm 中出现这些警告?
【问题讨论】:
-
在我看来,应该使用local scope。
-
据我了解(据我记得 Laravel 的工作原理),这是因为
@mixin行。@mixin的工作方式类似于 trait 的工作方式。因此,如果您有一个返回$this/self的特征中的方法,然后在类中使用该特征,则该方法的返回 ($this/self) 指向使用它的类。现在,AFAIRBuilder::where()也返回$this / self.. 但它实际上不是一个 trait .. 但 Laravel 神奇地使where()方法在这个类中可用...... -
问题来了:
$this / self实际上指向Builder类,但是当使用 作为特征(因为@mixin)时,它被解析为IDE 当前的MyModel类。 -
您可以使用
@mixin并忽略该问题(您可以通过Alt+Enter快速修复菜单使用错误抑制——它会为IDE 添加一条注释,告诉您在此处忽略该特定问题) .. 或删除@mixin并以不同方式声明这些方法。 AFAIK Laravel 帮助程序包应通过'@methodPHPDoc 行将所有此类 Builder 方法添加到 Model 类(查看详细信息)。另一个建议——试试 Laravel Idea 插件——它是一个付费插件,但它使使用 Laravel 代码变得更加容易,而且 AFAIK 它应该涵盖这些基本内容。 -
@LazyOne 感谢您精心制作的 cmets,它们甚至也适合完整的答案!那么,您是否认为 PhpStorm 中
@mixin的实现应该意识到这种情况并在该问题上暴露出细粒度的行为;还是需要解决源代码以避免问题?