将Laravel查询结果转换为类

时间:2015-08-07 08:28:17

标签: php laravel laravel-5 eloquent

使用语法DB::table('foo')创建查询时,它会创建一个泛型类(stdClass)。有没有办法将结果行强制转换为特定的类?

以下是一些示例代码,可以解释我想要做的事情:

$result = DB::table('foo')->get();
$converted = (Foo) $result; // Not going to work

我想将数组的所有(stdClass)对象强制转换为Foo类。

6 个答案:

答案 0 :(得分:29)

是的,您可以将结果保存到您想要的类中。我发现答案深埋在一堆半答案和混乱的问题中,构成了可怕的Laracasts.com forum。谢谢你在这里提问而不是那里。

获得结果后,使用模型类进行保湿:

$result = DB::table('foo')->get();
$converted = Foo::hydrate($result);

修改:如果有帮助

,也会找到一些documentation on the hydrate method

编辑2 我发现自己处于需要根据查询结果投出arraycollection的结果的情况。当一个集合被返回时,它被正确地水合,但当结果是一个数组时,它们只是stdClassI wrote a quick method添加到我的主model中,它收集了数组或对象或分页对象的集合,并正确地将其转换为我想要的对象。

答案 1 :(得分:1)

通常,您可以通过将PDO语句fetch_style设置为PDO :: FETCH_CLASS来实现此目的

$statement->fetchAll(PDO::FETCH_CLASS, "App\User");

如果您查看方法Illuminate\Database\Connection::select,您会看到虽然您可以设置fetch_style / fetchMode,但您不能使用第二个参数。

public function select($query, $bindings = array(), $useReadPdo = true)
{
    return $this->run($query, $bindings, function($me, $query, $bindings) use ($useReadPdo)
    {
        if ($me->pretending()) return array();

        // For select statements, we'll simply execute the query and return an array
        // of the database result set. Each element in the array will be a single
        // row from the database table, and will either be an array or objects.
        $statement = $this->getPdoForSelect($useReadPdo)->prepare($query);

        $statement->execute($me->prepareBindings($bindings));

        return $statement->fetchAll($me->getFetchMode());
    });
}

例如,在调用fetchAll调用PDOStatement::setFetchMode之前,你也无法访问该语句。

您可以尝试扩展Illuminate\Database\Connection并在其他数据库相关类中通过在必要时进行扩展和替换来利用它,但这似乎是一项艰巨的任务。

另一种选择是使用Eloquent,它会为您提供特定类型的类,但是您可以获得为模型对象加水的额外开销。

class Foo extends Illuminate\Database\Eloquent\Model {
    protected $table = 'foo';
}

Foo::all()
Foo::where('col', 1)->get()

答案 2 :(得分:1)

从laravel 5.4起

雄辩的模型没有hydrate()方法。

这已移至Eloquent Builder类。

https://laravel.com/api/5.4/search.html?search=hydrate

Eloquent Builder类需要一些操作才能使其手动工作

  1. 要初始化的查询构建器
  2. 与之水合的模型。

这是我在laravel 5.8代码中的工作示例:

            $instance = new $class;
            $table = $instance->getTable();

            /** @var \Illuminate\Database\Eloquent\Builder $eloquent_builder*/
            $eloquent_builder = new \Illuminate\Database\Eloquent\Builder(
                // the Query Builder!
                DB::connection($connection_name)
                ->table($table)
                ->select($columns)
                ->orderBy($order_by, $order)
            );


            // Tell Eloquent what you're using to hydrate the query
            $eloquent_builder->setModel($instance);


            return $eloquent_builder->get();

答案 3 :(得分:0)

你不能用这种方式输入它。
您可以构建更改您的Foo类来处理对象并使用它。

class Foo {
  private $object = null;
  public function __construct(stdClass $object) {
    $this->object = $object;
  }

  public function __get($property) {
    if (property_exists($this->object, $property)) {
      return $this->object->$property;
    }
  }

  public function __set($property, $value) {
    if (property_exists($this->object, $property)) {
      $this->object->$property = $value;
    }
    return $this;
  }

  public static function make(stdClass $object) {
    return new self($object);
  }

  public static function makeCollection(array $collection) {
    foreach($collection AS $key => $Item) {
      $collection[$key] = self::make($Item);
    }
    return $collection;
  }
}

$result = DB::table('foo')->get();
$converted = Foo::makeCollection($result);

答案 4 :(得分:0)

Laravel 5.8

在您要转换为的类(在本示例中为YourClass)中,您将需要这样的构造函数:

    /**
     * Use to initialize fields from DB query like:
     * $query->mapInto(YourClass::class)
     *
     * YourClass constructor.
     * @param \stdClass $data
     */
    public function __construct(\stdClass $data)
    {
        foreach ($data as $key => $value) {
            $this->$key = $value;
        }
    }

然后在您的查询中

$result = $query
->get()
->mapInto(YourClass::class);

$ result现在将包含YourClass个实例的集合,这些实例具有从查询中加载的字段。

答案 5 :(得分:-1)

是。例如:

  $query = DB::table('example_tbl')->where('id', $id)->get();
  $cast = (array)$query;
  var_dump($cast);