Hyperf 注解别用在模型上!
在 Hyperf 中,我们习惯将一些依赖的类以注解的方式引入进来,简单易用,代码也更简洁可读。
我们应该避免将 Model 用注解的方式引入进来,因为这会使 Model 变成单例,使用不当的话在某些场景会造成意向不到的结果。
测试
测试模型中使用 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();
}
查看结果
表中只插入了最后一次循环的数据
测试使用 New
public function testSave($data)
{
$test = new HyperfTest();
$test->name = $data['name'];
$test->save();
}
查看结果
结论
如果用注解的方式引入 Model,并且在 Model 中用 this 插入数据,在循环插入场景下,模型会认为这是对一个模型反复操作,就会导致只插入了最后一条数据,换成 New 就可以了,为了避免这种事情,我们在引用模型时不要用注解这种错误的方式引入了。
本作品采用《CC 协议》,转载必须注明作者和本文链接
一会儿
testInsert
,一会儿testSave
:joy:单例的不是Model,而是Command,因为Command只实例化了一次,而Model是它的属性,所以Model一直是同一个。
第一次循环的时候插入了"字符串1",此时$this->hyperfTest是id为1的资源句柄,循环第二次的时候就变成update了,因为$this->hyperfTest资源句柄指向不为空所以会被当做update处理,所以最终的结果会蒙蔽了你,而数据库是实实在在执行了两条SQL.
这篇文章可以撤销了 勿人子弟,这是你写的代码有问题,和注解没关系,首先不管 命令 运行多少次 你的循环在一个函数体里 他都要执行 for的次数次io操作,第二点 你在一个函数里多次调用同一个对象 他得到的结果也只能是这个对象的值,for没有实例化 新对象这才是根本原因,你想要三条插入 你可以用 $this->create,因为 $this->save 不只是插入 他还有更新功能。