Laravel DB:first()方法带来的Response内容必须是一个字符串

时间:2017-07-27 21:29:35

标签: php laravel eloquent

我使用Laravel Illuminate,当我使用first()方法获得单个结果时出现此错误:

The Response content must be a string or object implementing __toString(), "object" given.

return DB::table('todos')->where("title","your List")->first();

如果我用get()方法选择它可以工作:

return DB::table('todos')->where("title","your List")->get();

你知道第一个陈述有什么问题吗?

2 个答案:

答案 0 :(得分:3)

执行->get()后,您会收到Illuminate\Support\Collection个对象。响应可以返回此对象,因为它实现了__toString()方法:

/**
 * Convert the collection to its string representation.
 *
 * @return string
 */
public function __toString()
{
    return $this->toJson();
}

/**
 * Get the collection of items as JSON.
 *
 * @param  int  $options
 * @return string
 */
public function toJson($options = 0)
{
    return json_encode($this->jsonSerialize(), $options);
}

/**
 * Convert the object into something JSON serializable.
 *
 * @return array
 */
public function jsonSerialize()
{
    return array_map(function ($value) {
        if ($value instanceof JsonSerializable) {
            return $value->jsonSerialize();
        } elseif ($value instanceof Jsonable) {
            return json_decode($value->toJson(), true);
        } elseif ($value instanceof Arrayable) {
            return $value->toArray();
        } else {
            return $value;
        }
    }, $this->items);
}

正如您所看到的,它只是将整个集合转换为json。

但是当你执行->first()时,幕后发生的事情是Laravel执行->take(1)->get()->first(),因此查询被限制为一行,然后检索包含该行的结果的集合,最后你得到一个对象。

所以->first()调用是在幕后的集合上进行的,这意味着你没有得到另一个集合,而是一个数据库对象 - 可能属于Illuminate\Database\Query\Builder类,我不能非常记得。

由于该类没有实现__toString()方法,因此响应不知道如何处理它。相反,你得到一个错误。

您可以通过在对象上运行json_encode()或通过返回json响应来轻松模拟相同的响应。

答案 1 :(得分:0)

@JoelHinz已尽可能详细地说明了这一点。但是对这种行为感到好奇,我在Query builder's where clause

下的Laravel doc中发现了一些有趣的东西

enter image description here

使用DB Facade并调用get()会返回(StdClass)对象的集合。由于它驻留在Laravel的集合中,因此有一些方法可以将其底层属性转换为String。但是当你直接从查询构建器访问集合中的一个项目时,你有一个 StdClass对象,它没有实现__toString()(非常肯定)。

我认为同样的情况是如果你有一个集合,并且你检索一个底层数组说$collection[0]你将失去Laravel集合的_toString()的实现,因为你已经打开它现在有纯PHP数组。

此行为正是“查询”构建器的开发方式。为了更好地处理您的查询结果,您可以return json_encode($query_result)return response()->json($query_result)或使用Eloquent(如果您创建了模型),即return Todo::where("title","your List")->first();