Php 扩展laravelcreate():为什么文档说要将非静态方法重写为静态方法?

Php 扩展laravelcreate():为什么文档说要将非静态方法重写为静态方法?,php,laravel,upgrade,Php,Laravel,Upgrade,我有一个Laravel项目,我正在从5.3升级到5.4,这是在 在指南中,它说create方法已经移动到Builder类中,这个方法应该被称为newway$model=static::query()->create($attributes)。除了在升级指南中记录外,互联网上还有许多问题,例如和 我不明白的是为什么他们仍然将重写方法指定为静态的。新的create方法不再是静态的(因此是新的调用),但是,所有示例仍然定义了一个静态方法来覆盖它。如果我这样做,PHPStorm会给我以下(预期)错误:

我有一个Laravel项目,我正在从5.3升级到5.4,这是在

在指南中,它说create方法已经移动到Builder类中,这个方法应该被称为newway
$model=static::query()->create($attributes)。除了在升级指南中记录外,互联网上还有许多问题,例如和

我不明白的是为什么他们仍然将重写方法指定为静态的。新的create方法不再是静态的(因此是新的调用),但是,所有示例仍然定义了一个静态方法来覆盖它。如果我这样做,PHPStorm会给我以下(预期)错误:

无法将非静态方法生成器->创建([attributes:array=[])设为静态

为什么示例(包括官方文档)将其作为静态文件覆盖


假设这对其他人都有效,为什么我的不起作用呢?

所以这里有一个非常简短的解释。5.3及更早版本中的Laravel eloquent模型将
create
方法作为静态函数放在自己的类中。这是来源:

public static function create(array $attributes = [])
{
    $model = new static($attributes);
    $model->save();
    return $model;
}
同时,该模型具有以下定义

public function __call($method, $parameters)
{
    if (in_array($method, ['increment', 'decrement'])) {
        return $this->$method(...$parameters);
    }
    return $this->newQuery()->$method(...$parameters);
}
这意味着未在模型上定义的每个函数调用都将在
Builder
对象的新实例上调用

在5.4中,他们认为
create
似乎更适合
Builder
而不是模型本身,因此他们在那里采用了这种方法:

public function create(array $attributes = [])
{
    return tap($this->newModelInstance($attributes), function ($instance) {
        $instance->save();
    });
}
它基本上做了相同的事情,但是它更适合构建器,但是显著的区别是它不是静态的,因为对模型的所有类似静态的调用都被转发到
builder
实例

如果您确实在子类中重写了之前的方法,然后在某个时候调用了
parent::create
,这可能不再有效,因为parent实际上没有create,因此建议使用
static::query()->create(…)
的替代代码。实际上,调用
$this->\u调用('create',…)
可能也会起作用,但这很难理解,而且会使IDE在进行重构时陷入混乱,因为这是一个无法检测的调用
Builder::create

现在最后一点是
模型
上也有
@mixinbuilder
@mixin
表示一个类基本上是在当前类中混合的,以扩展其功能,并用于在以非标准OOP方式(如本例中的
\uuuu call
\uu callStatic
发生时,向IDE提示这种情况正在发生)。这导致您的IDE认为您在
Builder
上重载
create
,因为IDE认为
Builder
Model
混合在一起,但事实上它并不是完全混合在一起的,而是作为静态混合在一起的(据我所知,PhpStorm在处理这个概念时有困难)


就是这样。我希望这是有道理的

您是否在您的模型中定义了您的?从技术上讲,它不再是重写,因为父方法已被删除,您可以将其保持为静态以维护签名。@apokryfos我在一个扩展模型的类中拥有它,PHPStorm说“重写类“Builder”中的方法”。是不是我的代码可能是正确的,我不希望PHPStorm认为它是一个被重写的方法?抱歉耽搁了,我只是做兼职,但我确实想解决我的问题。我不应该这么说。如果您正在使用任何类型的ide帮助程序,例如,那么您应该为L5.4刷新它。还要确保您没有在模型中声明
@mixinbuilder
。无论如何,PhpStorm假设模型中的方法会覆盖Builder中的方法是不正确的,因为模型和Builder没有直接关系。。。在我的代码中没有mixin Builder标记,但是Laravel代码“\vendor\Laravel\framework\src\illumb\Database\Eloquent”在抽象类模型的文档注释中包含“@mixin\illumb\Database\Eloquent\Builder”。但是,我将composer laravel版本从5.4.*(正如升级指南所说)更改为5.4.0,@mixin标记不再存在,因此错误消失了。这很好(耶!),但是,当有更新并且它们被添加回来时会发生什么呢?我没有看到5.4.*的升级指南。我不认为它会在没有充分理由的情况下重新添加。我使用的5.5版本中肯定没有。然而,
@mixin
只是一个文档提示,PhpStorm读取并假设它是准确的。与代码不同,您不能真正地对注释或文档进行单元测试,因此文档总是有可能落后于实际更改。我不会太担心的。很好的解释,谢谢。对于具有相同问题的其他人,这些是导致/解决问题的版本。在Laravel5.4.29中引入了breaking-mixin标记,因此对于那些更新到5.4的人,您将需要5.4.28。如果使用barryvdh/laravel ide helper,版本“^2.4”(我认为基本上是2.x,其中x>4)会自动插入中断的mixin标记,因此最好使用“>=2.3”