使用语法DB::table('foo')
创建查询时,它会创建一个泛型类(stdClass)。有没有办法将结果行强制转换为特定的类?
以下是一些示例代码,可以解释我想要做的事情:
$result = DB::table('foo')->get();
$converted = (Foo) $result; // Not going to work
我想将数组的所有(stdClass)对象强制转换为Foo类。
答案 0 :(得分:29)
是的,您可以将结果保存到您想要的类中。我发现答案深埋在一堆半答案和混乱的问题中,构成了可怕的Laracasts.com forum。谢谢你在这里提问而不是那里。
获得结果后,使用模型类进行保湿:
$result = DB::table('foo')->get();
$converted = Foo::hydrate($result);
修改:如果有帮助
,也会找到一些documentation on thehydrate
method
编辑2 我发现自己处于需要根据查询结果投出array
或collection
的结果的情况。当一个集合被返回时,它被正确地水合,但当结果是一个数组时,它们只是stdClass
。 I 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)
雄辩的模型没有hydrate()方法。
这已移至Eloquent Builder类。
https://laravel.com/api/5.4/search.html?search=hydrate
这是我在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);