Hyperf 注解别用在模型上!

在 Hyperf 中,我们习惯将一些依赖的类以注解的方式引入进来,简单易用,代码也更简洁可读。

我们应该避免将 Model 用注解的方式引入进来,因为这会使 Model 变成单例,使用不当的话在某些场景会造成意向不到的结果。

Hyperf 注解别用在模型上!

测试

测试模型中使用 this

新建一个 TestCommand,写入如下执行代码

<?php

namespace App\Command;

...

/**
 * @Command
 */
class TestCommand extends HyperfCommand
{
    /**
     * @Inject()
     * @var HyperfTest
     */
    protected $hyperfTest;

    public function handle()
    {
        for ($i = 1; $i <= 2; $i++) {
            $this->hyperfTest->testSave([
                'name' => "字符串$i"
            ]);
        }

        $this->line('Test Success!', 'info');
    }
}

新建一个 Model,写入如下模型代码

public function testSave($data)
{
    $this->name = $data['name'];
    $this->save();
}

查看结果

Hyperf 注解别用在模型上!
表中只插入了最后一次循环的数据

测试使用 New

public function testSave($data)
{
    $test = new HyperfTest();
    $test->name = $data['name'];
    $test->save();
}

查看结果

Hyperf 注解别用在模型上!

结论

如果用注解的方式引入 Model,并且在 Model 中用 this 插入数据,在循环插入场景下,模型会认为这是对一个模型反复操作,就会导致只插入了最后一条数据,换成 New 就可以了,为了避免这种事情,我们在引用模型时不要用注解这种错误的方式引入了。

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 4

一会儿testInsert,一会儿testSave :joy:

3年前 评论

单例的不是Model,而是Command,因为Command只实例化了一次,而Model是它的属性,所以Model一直是同一个。

3年前 评论
邢闯洋 (楼主) 3年前

第一次循环的时候插入了"字符串1",此时$this->hyperfTest是id为1的资源句柄,循环第二次的时候就变成update了,因为$this->hyperfTest资源句柄指向不为空所以会被当做update处理,所以最终的结果会蒙蔽了你,而数据库是实实在在执行了两条SQL.

2年前 评论

这篇文章可以撤销了 勿人子弟,这是你写的代码有问题,和注解没关系,首先不管 命令 运行多少次 你的循环在一个函数体里 他都要执行 for的次数次io操作,第二点 你在一个函数里多次调用同一个对象 他得到的结果也只能是这个对象的值,for没有实例化 新对象这才是根本原因,你想要三条插入 你可以用 $this->create,因为 $this->save 不只是插入 他还有更新功能。

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!