舒适提示:篇幅较长,阅读须要5-10分钟。php
一个比较完善的表中基本上都会有type
,status
字段,来区分类型和状态,如今的问题就是当api接口返回数据后,前端人员根本不知道你返回的type
或者status
字段是什么意思,以前的作法是用if
流程语句判断,将status=1
手动转换成“启用”,status=2
转换成“禁用”(刚入门的时候我就是这么作的)。前端
这样的话,是否是很复杂呢?既然复杂,那么就改进它,咱们能够加一个type_str
说明字段,来讲明type
中数字所表示的含义,同理,咱们给status
配备一个status_str
。ok,解决办法有了,可是若是直接加在数据库的话,又很不方便,因此咱们要借用一下helpers.php
。laravel
这是一个自定义常量配置文件,路径在config/constants.php
,咱们在里面定义咱们的常量:数据库
<?php
return [
'APP_NAME' => 'my project',
'APP_URL'=> '你的域名',
'USER_TYPE' => [
1 => '代理商',
2 => '分销商',
3 => '普通用户',
],
复制代码
你们能够看到,我定义了一个USER_TYPE
常量,为何叫这个名字呢,下面会解释。json
app/helpers.php
:<?php
if (!function_exists('constants')) {
function constants(string $constName, $trans = false) {
$config = config('constants.' . strtoupper($constName));
if ($trans === false) {
return $config;
}
if ($trans === 'label') {
return array2label($config);
}
}
}
if (!function_exists('array2label')) {
function array2label(array $arr) {
$ret = [];
foreach ($arr as $key => $item) {
$ret[] = ['label' => $item, 'value' => $key];
}
return $ret;
}
}
复制代码
来稍微解释一下,我这里定义了一个constants
函数,他的做用是当咱们传入参数时,经过config
辅助函数从constants
配置文件里面获取相应的值,完整的流程会在最后说明。api
//将files添加到autoload中
"autoload": {
"files": [
"app/helpers.php",
],
"classmap": [
"app/Libraries",
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/"
}
},
复制代码
composer dump-autoload
复制代码
基本配置到这里就差很少了,咱们在model
中追加type_str
字段。数组
protected $appends = ['type_str'];
复制代码
而后给type_str
“赋值”,这里不太懂的能够查看文档 追加json值:bash
public function getTypeStrAttribute()
{
return array_get(constants( 'USER_TYPE'), $this->getAttribute('type'));
}
复制代码
这里调用了以前在helpers.php
中定义好的constants
函数,array_get
方法使用”.“号从嵌套数组中获取值,固然也不必定用array_get
,也能够用其余。app
到上一步,咱们的需求基本上就实现了。可是,我一个项目里大约有10多张表使用到了type
以及status
字段,每一个模型中都写这么一段代码,不太符合优雅的概念,因此完善过程当中又使用到了trait
。composer
关于trait,它是为相似 PHP 的单继承语言而准备的一种代码复用机制,具体能够参阅PHP文档。
路径在app/Traits/TypeTrait.php
<?php
namespace App\Traits;
trait TypeTrait
{
public function getTypeStrAttribute()
{
return array_get(constants(class_basename(static::class) . '_TYPE'), $this->getAttribute('type'));
}
}
复制代码
回到咱们Model模型,追加字段不变,可是不用再进行“赋值”操做了,只需:
use TypeTrait;
protected $appends = ['type_str'];
复制代码
还记得上面挖的坑为何要命名为USER_TYPE
吗?就是为这里作铺垫的,仔细看TypeTrait.php
文件,class_basename
的做用是返回给定类删除命名空间的类名,好比在uesr模型中它返回的就是user,这样就方便咱们代码的复用。
可能有人看到这里仍是有些迷糊,你说了半天这究竟是咋用的。让咱们一块儿走一遍流程(按照代码进行流程):
User控制器调用查询方法,使用toArray()
返回接口须要的字段。
查询的时候就经过User模型查询数据,使用的同时就追加了type_str字段,这个字段不是数据表中有的,而是咱们临时添加上去的,因此咱们须要定义它的值。
因而User模型调用了TypeTrait.php中的getTypeStrAttribute()
方法,这个方法有三层嵌套:
3.1 最里面的是class_basename返回给定类删除命名空间的类名,若是咱们是经过User模型调用的就是User,而后使用“.”拼接了字符串,最后获得的是User_TYPE。
3.2 中间的一层,constants函数接收到了咱们的参数“User_TYPE”,strtoupper将“User_TYPE“所有转换为大写字符,经过config
在自定义常量配置文件constants.php中取值,返回一个USER_TYPE数组
。
3.3 回到 getTypeStrAttribute()
方法,最外面一层经过array_get匹配出type字段相对应的说明文字并返回,
这样给追加字段赋值就成功了。
结束语:一共用了两个小时完成,修修改改了三遍,可能仍是会有一些细小的纰漏,若是有什么问题,欢迎评论指正,或者也能够纠错改正!