Php Elount模型上的自定义字段名
我有一个表Php Elount模型上的自定义字段名,php,laravel,laravel-5,eloquent,Php,Laravel,Laravel 5,Eloquent,我有一个表posts,这个表有一些列,比如pst\u id,pst\u title,pst\u content,pst\u category\u id等等。我想在json输出中用一些更好的名称表示这些字段,实际上我正在尝试从列名中删除前缀pst 我测试了多种方法。起初,我试图在DB层上为这些列创建一个别名,例如Post::select(['pst\u id as id'])->get()。这种想法通常很糟糕,因为它使整个软件中的列名不一致(每个开发人员可能都有命名字段的约定)。所以我坚持要找到一
posts
,这个表有一些列,比如pst\u id
,pst\u title
,pst\u content
,pst\u category\u id
等等。我想在json输出中用一些更好的名称表示这些字段,实际上我正在尝试从列名中删除前缀pst
我测试了多种方法。起初,我试图在DB层上为这些列创建一个别名,例如Post::select(['pst\u id as id'])->get()
。这种想法通常很糟糕,因为它使整个软件中的列名不一致(每个开发人员可能都有命名字段的约定)。所以我坚持要找到一种方法来命名模型层上的列
下一个解决方案是使用访问器
和变异器
。虽然它涵盖了前一种方法的问题,但要为每个模型实现20种方法确实很困难!20x100~2000种方法!!!:/
我测试的最后一个解决方案是关于使用的mappable
特性。这真的很好,我可以将所有旧字段放到$hidden
属性中,并将新字段添加到$appends
中,以便在输出时显示。但是这个解决方案也有一个问题。如果我将所有新字段添加到$appends
,当我使用select
语句选择某些列时,未选择的列将在输出时显示为null
值:|。嗯,我尝试在一个基本模型上重写mappedselect
和parseMappings
方法,以便动态地将新名称添加到$appends
,但我并不满意。事实上,它在使用上变得非常棘手,我不确定团队是否能够接受它并轻松地使用它
这就是问题所在:“有没有办法为eloquent重命名输出列的名称?”。GoLang有一个非常好的特性,称为结构标记。可以为结构定义一些标记,例如:
type Post struct {
Pst_id int `json:"id"`
Pst_title string `json:"title"`
Pst_content string `json:"content"`
}
{
"id": 23,
"title": "Custom Field Tags for Eloquent",
"content": "I tried a lot of things, but they are hard. I'm a programmer so I'm lazy! What can I do?",
}
当您使用json.Marshal
为Post
结构生成json时,基于标记,它将为您提供如下json:
type Post struct {
Pst_id int `json:"id"`
Pst_title string `json:"title"`
Pst_content string `json:"content"`
}
{
"id": 23,
"title": "Custom Field Tags for Eloquent",
"content": "I tried a lot of things, but they are hard. I'm a programmer so I'm lazy! What can I do?",
}
我认为我们在php世界中没有类似的东西,但是有没有任何方法可以使用后面的思想在Go中实现类似于标记结构的东西
欢迎任何意见和想法 我可能会用联盟的
基本上创建一个映射类并将其应用于集合
$posts = Post::all();
$manager = new Manager();
$manager->setSerializer(new CursorSerializer());
$resource = new Collection($posts, new PostTransformer());
$formattedCollection = $manager->createData($resource);
Transformer类将如下所示
<?php
namespace App;
use App\Post;
use League\Fractal;
use League\Fractal\TransformerAbstract;
class PostTransformer extends TransformerAbstract{
public function transform(Post $post)
{
return [
'id' => (int) $post->pst_id,
'title' => $post->pst_name,
'content' => $post->pst_uuid,
];
}
}
这些文档非常好,而且实现起来非常简单。我可能会使用联盟的文档
基本上创建一个映射类并将其应用于集合
$posts = Post::all();
$manager = new Manager();
$manager->setSerializer(new CursorSerializer());
$resource = new Collection($posts, new PostTransformer());
$formattedCollection = $manager->createData($resource);
Transformer类将如下所示
<?php
namespace App;
use App\Post;
use League\Fractal;
use League\Fractal\TransformerAbstract;
class PostTransformer extends TransformerAbstract{
public function transform(Post $post)
{
return [
'id' => (int) $post->pst_id,
'title' => $post->pst_name,
'content' => $post->pst_uuid,
];
}
}
这些文档非常好,实现起来非常简单。第一步是覆盖这些模型上的几个方法。第一个方法是,当您访问模型的属性时,将调用该方法,以便您可以访问它。您希望能够在不使用
pst\uu
前缀的情况下访问该属性,因此可以执行以下操作:
public function getAttribute($key)
{
if(array_key_exists($prefixedKey = 'pst_'.$key, $this->attributes)) {
return $this->attributes[$prefixedKey];
}
return parent::getAttribute($key);
}
然后,为了确保在强制转换为json时键没有前缀,您将覆盖输出json时调用的方法,并将尊重您的$hidden
、$visible
、$casts
和$dates
数组。这大概是:
public function attributesToArray()
{
$attributes = parent::attributesToArray();
$mutated = [];
foreach ($attributes as $key => $value) {
$mutated[preg_replace('/^pst_/', '', $key)] = $value;
}
return $mutated;
}
要实现这些特性,您可以使用实现这些方法的抽象类扩展
模型类,并让您的类扩展该基类,或者使用这些方法创建特性,并让您的类实现该特性。第一步是覆盖这些模型上的两个方法。第一个方法是,当您访问模型的属性时,将调用该方法,以便您可以访问它。您希望能够在不使用pst\uu
前缀的情况下访问该属性,因此可以执行以下操作:
public function getAttribute($key)
{
if(array_key_exists($prefixedKey = 'pst_'.$key, $this->attributes)) {
return $this->attributes[$prefixedKey];
}
return parent::getAttribute($key);
}
然后,为了确保在强制转换为json时键没有前缀,您将覆盖输出json时调用的方法,并将尊重您的$hidden
、$visible
、$casts
和$dates
数组。这大概是:
public function attributesToArray()
{
$attributes = parent::attributesToArray();
$mutated = [];
foreach ($attributes as $key => $value) {
$mutated[preg_replace('/^pst_/', '', $key)] = $value;
}
return $mutated;
}
要实现这些,您可以使用实现这些方法的抽象类扩展模型
类,让您的类扩展基类,或者使用这些方法创建特性,让您的类实现该特性。我喜欢您的方法!事实上,我是laravel的新手,我不知道将对象转换成数组的机制。我认为通过覆盖这些方法和其他一些方法(比如与select
method相关的方法),我可以实现我的目标!谢谢我喜欢你的方法!事实上,我是laravel的新手,我不知道将对象转换成数组的机制。我认为通过覆盖这些方法和其他一些方法(比如与select
method相关的方法),我可以实现我的目标!谢谢