Json 在Laravel中手动构建可序列化的集合

Json 在Laravel中手动构建可序列化的集合,json,rest,serialization,laravel,laravel-4,Json,Rest,Serialization,Laravel,Laravel 4,我正在用Laravel编程一个RESTful服务。现在我在序列化手动创建的对象列表时遇到了一些问题 我有一个User对象,它应该有一个属性solarpanels。我使用如下访问器实现了此属性: function getSolarplantsAttribute() { $solarplants = array(); $mastergrants = MasterGrant::where('userid', '=', $this->id)->get(); forea

我正在用Laravel编程一个RESTful服务。现在我在序列化手动创建的对象列表时遇到了一些问题

我有一个
User
对象,它应该有一个属性
solarpanels
。我使用如下访问器实现了此属性:

function getSolarplantsAttribute() {
    $solarplants = array();
    $mastergrants = MasterGrant::where('userid', '=', $this->id)->get();
    foreach ($mastergrants as $mastergrant) {
        $masternode = Masternode::find($mastergrant->masternodeid);
        if ($masternode == null) {
            continue;
        }
        $solarplant = SolarPlant::find($masternode->fieldID);
        $solarplants[] = $solarplant;
    }
    return $solarplants;
}
不幸的是,我必须以这种复杂的方式来做,因为数据库方案就是这样设计的,我不能改变它

现在我有了一个资源控制器,我想通过这种方式实现:

public function index()
{
    $user = Auth::user();
    $solarplants = $user->solarplants;
    return $solarplants;
}
不幸的是,这种方式会将对象序列化为:

[{"timestamps":false,"incrementing":true,"exists":true}]
这是错误的,它只是在分析对象变量,而不是应该如何做,以及我是如何设计有说服力的对象的。所以我试着做到这一点:

public function index()
{
    $user = Auth::user();
    $solarplants = $user->solarplants;
    $convertedPlants = array();
    foreach ($solarplants as $solarplant) {
        $convertedPlants[] = $solarplant->toJson();
    }
    return $convertedPlants;
}
这种方法很有效,但现在Laravel正在转义我的JSON字符串,它确实改变了JSON的含义,因此在前端不再可处理。我还尝试这样强制转换:
$solarplant->toArray()
,但随后
solarplant
对象的访问器被忽略

然后我有了另一个想法(就像当我
返回SolarPlant::all();
可以正常工作并被序列化一样)。我想手动创建一个集合。但这又会导致访问器无法正确序列化

所以基本上,我的问题还没有合适的解决方案。你们有什么建议吗

编辑以简化:

我试图把问题的核心解释得更简单、更抽象一些。我的
SolarPlant
对象是一个有访问器的雄辩对象。此访问器本身返回单个雄辩对象或雄辩对象列表。现在,当我这样做时,一切正常:

Route::get('test', function () {
    return SolarPlant::find(1);
});
但通过这种方式,序列化不再起作用,而是序列化原始php对象,而不是以雄辩的方式:

Route::get('test', function () {
  $solarplants = array();
  $solarplants[] = SolarPlant::find(1);
  $solarplants[] = SolarPlant::find(1);
  return $solarplants;
});

但我刚刚还发现,SolarPlant::all()并没有像我预期的那样正常工作。访问器也没有得到很好的处理。

您可以重写SolarPlant toArray/toJson方法以包含所需内容:

class SolarPlant {
    ...
    public function toArray() {
        $array = parent::toArray();
        $array['mutator_x'] = $this->mutator_x;
        return $array;
    }
}

如果您只需要
JSON
格式,您可以保持
getSolarplantsAttribute
不变,并将
index
函数修改为:

public function index()
{
    $user = Auth::user();
    return json_encode($user->solarplants);
}
如果您有
SolarPlant
的任何访问器,它们将被执行

我已经测试过了,它似乎工作得很好,accessor启动了。我添加了以下访问器:

public function getEmailAttribute() {
    return mb_strtoupper($this->attributes['email']);
}
当我以同样的方式获得用户时,我会收到大写的电子邮件(在数据库中是小写的)

我已经测试过将您的
getSolarPlantAttribute
函数更改为:

function getSolarplantsAttribute()
{
    $users[] = User::find($this->id);
    $users[] = User::find($this->id);
    return $users;
}

我得到了预期的结果

你是说访问器不是变异器吗?你没有在这里设置任何东西,所以我认为你想使用accessor,对吗?你是对的,我对命名感到困惑,编辑了它。什么是
SolarPlants::all
?你们有两种型号的SolarPlant和SolarPlants吗?对不起,那是个错误,应该是SolarPlant::all()。但在我的代码中它是正确的;)对不起,我不能再帮你了。我看这里没什么问题。一切都会好起来的不,那不行。我的访问器位于$appends数组中。正如我所说,返回SolarPlant:all()会正确序列化,同时返回SolarPlant:find(1)也会正确序列化。因此,它并没有以雄辩的风格进行序列化,而只是罕见的PHP对象。为什么?(编辑:我的虚拟数据库中只有一个solarplant,这就是为什么它在列表中只有一个json对象)@Chris尝试将您的
GetSolarPlantAttribute
更改为真正基本的内容。我把$users[]=User::find(1)放在那里$users[]=User::find(1);返回$users只是为了测试它,我无法让它工作。我更新了我原来的帖子,使它更简单,使我的问题更容易理解。