说明#
此文章是 [Laravel 5.3 新功能] 系列的第三篇文章,Eloquent 方法 FirstOrCreate 增加新参数。
[Laravel 5.3 新功能] 系列完整文章列表请见:https://laravel-china.org/topics/2638
FirstOrCreate 介绍#
Eloquent 的 firstOrCreate() 可以接收一个数组类型的参数,根据传入的参数检查 Eloquent 对应的属性是否存在,并执行以下逻辑:
- 属性如存在,则返回该实例;
- 属性如不存在,则先创建它,再返回创建的实例。
5.3 之前,firstOrCreate() 的局限性#
首先我们先创建如下代码:
$user = User::firstOrCreate(['name' => 'phphub-monkey']);
上面的代码将先判断 User 里是否有 name
为 phphub-monkey 的对象,如果没有则创建此对象。
在通常情况下,我们在创建用户时不会只生成 name
数据,同时还需生成邮箱 (email)、头像 (avatar)、性别 (gender) 等数据。在 5.3 之前,我们只能这样写:
$user = User::firstOrCreate([
'name' => 'phphub-monkey',
'email' => 'jin114001251@gmail.com',
'avatar' => 'http://....',
'gender' => 'male',
]);
这样看起来没什么问题,运行后数据貌似也能正常生成,但实际上,上文代码运行的查询语句如下:
select * from `users` where `users`.`deleted_at` is null and
(
`name` = 'phphub-monkey'
and `email` = 'jin114001251@gmail.com'
and `avatar` = 'http://......'
and `gender` = 'male'
) limit 1
可以看出,这条查询语句是不符合我们要求的,它会认为只有同时满足四个条件,才能确认此用户存在。其实只要查出 name
为 phphub-monkey 的数据存在,就可认定此用户已经存在,无需再生成数据。
可能引起的不良后果#
如果用户表已经存在 name 为 phphub-monkey,但是 email 为 phphub@phphub.com 的用户,程序依旧认为此用户不存在,会直接创建 phphub-monkey 用户,导致数据表里出现两个 phphub-monkey 用户,或者直接报错(如果 name 字段设置为 unique 的话)。
5.3 的解决方案#
现在,在 5.3 中我们可以这么写:
$user = User::firstOrCreate(
['name' => 'phphub-monkey'],
[
'email' => 'jin114001251@gmail.com',
'avatar' => 'http://....',
'gender' => 'male',
]
]);
这样一来,程序只会查询 name
为 phphub-monkey 的数据是否存在,如果不存在,才将 name, email, avatar, gender 数据一并生成。
一句话总结#
在 5.3 里,firstOrCreate() 有两个数组类型的参数:
- 第一个参数用于确认 Eloquent 对象是否存在;
- 第二个参数用于生成 Eloquent 对象时需要附加生成的属性。
全文完。