MVC开发模式中。Model应该做为所有的数据来源。V只做展示,而C可以做一些数据的处理工作。所以在分工中,Model应该仔细去品一品到底应该怎么使用更好。
下面我将自己平时开发中,关于Model应该处理的部分做为一个案例展示分享给大家。
官方和其它案例里一般都会使用User模型,我这些将User修改一个名字为 Staff 雇员表,以区别官方案例。
Staff表里有的字段如下,每个人的情况不一样,我以自己写的一个小管理系统为例:
`id` smallint UNSIGNED NOT NULL,
`group_id` smallint UNSIGNED NOT NULL COMMENT '部门ID',
`username` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名',
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '名字',
`password` varchar(60) COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码',
`email` varchar(180) COLLATE utf8mb4_general_ci NOT NULL COMMENT '邮箱',
`mobilenumber` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '手机',
`title` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '职位',
`sex` tinyint(1) NOT NULL DEFAULT '2' COMMENT '姓别(0女,1男,2未知)',
`last_login_ip` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '最后登陆IP',
`avatar` varchar(180) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '头像URL',
`identity` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '身份证号码',
`login_count` int UNSIGNED NOT NULL DEFAULT '0' COMMENT '登陆次数',
`customers_count` int UNSIGNED NOT NULL DEFAULT '0' COMMENT '客户数',
`contacts_count` int UNSIGNED NOT NULL DEFAULT '0' COMMENT '联系人数',
`follows_count` int UNSIGNED NOT NULL DEFAULT '0' COMMENT '跟进数',
`appointments_count` int UNSIGNED NOT NULL DEFAULT '0' COMMENT '预约数',
`remember_token` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '记住登陆状态',
`status` tinyint NOT NULL DEFAULT '0' COMMENT '状态(0正常,1离职)',
`login_at` datetime DEFAULT NULL,
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`avatar_at` datetime DEFAULT NULL COMMENT '头像修改时间'
以上字段 可以根据自己的实际情况进行增减。
常规的Model设计中,只做了数据查询,并未做更多的数据处理。我将会在下面的示例中,一步一步介绍Model强大的数据处理功能。
<?php
namespace AppModelsStaff;
/**
* Copyright (C) 2022 : Chongqing Enzu Technology Co., LTD(cqseo.net)
* LICENSE : http://www.apache.org/licenses/LICENSE-2.0
* [KwokCMS] Ver 1.0 (C) 2022: Mr.Kwok
* FilePath: /app/Models/Staff/Staff.php
* Created Time: 2022-04-24 21:42:37
* Last Edit Time: 2023-03-17 16:02:03
* Description: 员工表Model(Staff复数没有s)
*/
use IlluminateDatabaseEloquentFactoriesHasFactory;//模型工厂
use IlluminateFoundationAuthUser as Authenticatable;//用户验证
use IlluminateNotificationsNotifiable;//消息报告
use LaravelSanctumHasApiTokens;//API Tokens
use IlluminateDatabaseEloquentCastsAttribute; //字段修改器
use IlluminateSupportStr; //字符处理
use IlluminateSupportFacadesStorage; //文件处理
class Staff extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
public $timestamps = false; //不维护时间(当用户更新资料时手工维护)
/**
* 允许通过Model操作的字段
* @var array<int, string>
*/
protected $fillable = [
'group_id',
'username',
'name',
'password',
'email',
'mobilenumber',
'title',
'sex',
'last_login_ip',
'avatar',
'avatar_at',
'created_at',
'updated_at',
'login_at',
'identity',
'remember_token',
'status'
];
}
理论上来讲,上面的Model代码就可以正常的使用了。但为了在多场景下运行,我们应该增加更多的数据处理功能,以达到最大的代码复用。
在Model增加下面的代码(只读):
//头像链接
public function getAvatarUrlAttribute()
{
return empty($this->attributes['avatar']) ?
asset('user' . $this->attributes['sex'] . '.jpg') : //通过sex生成头像
Storage::url($this->attributes['avatar']);
}
如果用户未上传头像时,我们可以调用资源里的默认头像,还可以根据性别去处理不同的样式。这样我们在View或者Controller里直接使用$model->avtatrurl 属性获取到此字段。
通过 get***Attribute()可以生成新的字段处理以供只读,或者修改原字段的属性,那么我们也可以使用set***Attribute()方式,去处理写入字段时新增加数据:
// 定义模型的修改器(Mutator)
public function setPasswordAttribute($value)
{
$this->attributes['password'] = bcrypt($value); // 在设置 password 字段值时的处理逻辑
}
这样我们需要写2个方法分别去处理读与写,当前Laravel还提供了另一种处理方式供大家选择,请看下面的:
有的字段我们希望在输入时做一些替换,或者大小写转换操作,可以使用统一处理方式:
//处理email属性
protected function email(): Attribute
{
return Attribute::make(
set: fn ($value) => Str::lower($value),//数据写入时转为小写
get: fn ($value) =>'Emain:'.$value//数据读取时增加内容
);
}
有一些字段我们不希望被展示出来,所以可以通过设置属性隐藏:
/**
* 序列化时(如:Json),需要隐藏的字段
* @var array<int, string>
*/
protected $hidden = [
'password', 'remember_token',
];
这里我们将密码与记住Token项的字段隐藏起来。
在Laravel里有一个 is_admin的检查管理员属性,我们尝试实现一下:
public function isAdmin()
{
return $this->group_id == 1;//用户组1
}
在代码调用中,可以通过$model->isAdmin()来判断是否为管理员用户。
我们如果要查询某个用户下所有的文章,可以使用关联的方式,关联有很多种,也相对比较复杂,这些做一个简单的一对多案例:
// 定义模型与其他模型的关联关系
public function posts()
{
return $this->hasMany(Post::class);
}
在查询时,我们需要针对数据增加一些查询限制,我们可以通过下面的方式来实现:
// 定义模型的作用域(Scope)
public function scopeStatus($query)
{
return $query->where('status', 0);// 在查询中添加一个作用域条件
}
查询所有状态为0的在职员工。
除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:https://www.55mx.com/post/240
《【Laravel经验】强大的Model应该这样用》的网友评论(0)