75142913在线留言
【Laravel经验】强大的Model应该这样用_PHP技术_网络人

【Laravel经验】强大的Model应该这样用

Kwok 发表于:2023-04-23 09:23:39 点击:442 评论: 0

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设计中,只做了数据查询,并未做更多的数据处理。我将会在下面的示例中,一步一步介绍Model强大的数据处理功能。

1、基本的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代码就可以正常的使用了。但为了在多场景下运行,我们应该增加更多的数据处理功能,以达到最大的代码复用。

2、处理用户头像链接

在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还提供了另一种处理方式供大家选择,请看下面的:

3、处理输入项

有的字段我们希望在输入时做一些替换,或者大小写转换操作,可以使用统一处理方式:

 

//处理email属性
protected function email(): Attribute
{
    return Attribute::make(
        set: fn ($value) => Str::lower($value),//数据写入时转为小写
        get: fn ($value) =>'Emain:'.$value//数据读取时增加内容
    );
}

4、隐藏字段

有一些字段我们不希望被展示出来,所以可以通过设置属性隐藏:

/**
 * 序列化时(如:Json),需要隐藏的字段
 * @var array<int, string>
 */
protected $hidden = [
    'password', 'remember_token',
];

这里我们将密码与记住Token项的字段隐藏起来。

5、验证权限

在Laravel里有一个 is_admin的检查管理员属性,我们尝试实现一下:

public function isAdmin()
{
    return $this->group_id == 1;//用户组1
}

在代码调用中,可以通过$model->isAdmin()来判断是否为管理员用户。

6、定义关联

我们如果要查询某个用户下所有的文章,可以使用关联的方式,关联有很多种,也相对比较复杂,这些做一个简单的一对多案例:

// 定义模型与其他模型的关联关系
public function posts()
{
    return $this->hasMany(Post::class);
}

7、定义模型的限制器

在查询时,我们需要针对数据增加一些查询限制,我们可以通过下面的方式来实现:

 // 定义模型的作用域(Scope)
 public function scopeStatus($query)
 {     
     return $query->where('status', 0);// 在查询中添加一个作用域条件
 }

查询所有状态为0的在职员工。

 

除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:https://www.55mx.com/post/240
标签:laravelmodel
0
感谢打赏!

《【Laravel经验】强大的Model应该这样用》的网友评论(0)

本站推荐阅读

热门点击文章