Laravel 5.1 DB:select toArray()

41

我有一个很长的SQL语句,我是这样执行它的:

$result = DB::select($sql);

例如

$result = DB::select('select * from users');
我希望结果是一个数组,但现在它返回的是这样的结构,一个包含对象的数组...
Array
(
    0 => stdClass::__set_state(array(
        'id' => 1,
        'first_name' => 'Pavel',
        'created_at' => '2015-02-23 05:46:33',
    )),
    1 => stdClass::__set_state(array(
        'id' => 2,
        'first_name' => 'Eugene',
        'created_at' => '2016-02-23 05:46:34',
    )),
...etc...

)

14个回答

55

看起来你需要将stdClass对象转换为数组,这样你就可以得到你想要的结构。

$result = array_map(function ($value) {
    return (array)$value;
}, $result);

好主意!你确定Eloquent没有提供这个功能吗? - Yevgeniy Afanasyev
4
你正在使用查询构建器,而不是Eloquent,它可以表达出来,但没有那么流畅。 - huuuk
1
$result = array_map(fn($x) => (array)$x, $result); - Bishal Paudel

34

从性能的角度来看,最好的解决方案是改变从数据库中获取数据的方法:

// get original model
$fetchMode = DB::getFetchMode();
// set mode to custom
DB::setFetchMode(\PDO::FETCH_ASSOC);
// get data
$result = DB::select($sql);
// restore mode the original
DB::setFetchMode($fetchMode);

很明显,如果你想将所有数据作为数组获取,只需要在config/database.php中进行以下更改:

'fetch'       => PDO::FETCH_CLASS,

进入

'fetch'       => PDO::FETCH_ASSOC,

然后只运行:

$result = DB::select($sql);

会返回一个多维数组而不是对象数组


1
我找到了与此主题相关的答案,我认为这可以改进@Marcin的建议。https://dev59.com/lXfZa4cB1Zd3GeqPX_P9#19369644 - Jose Mujica
16
我在 Laravel 5.4 中遇到了这个错误:Call to undefined method Illuminate\Database\MySqlConnection::getFetchMode() - Ryan
这正是我所寻找的。谢谢。 - Evgeniy Maynagashev
我在Laravel Framework 8.26.1中遇到了以下错误-- 调用未定义的方法Illuminate\Database\MySqlConnection::setFetchMode() - Javed Iqbal
1
这个解决方案在 Laravel 5.4 之后显然不再适用。 - Carmageddon
显示剩余2条评论

13

这里有另一种方法值得一提:

$resultArray = json_decode(json_encode($result), true);

1
这只是除了在 Laravel 上监听之外的另一种方式,太遗憾了。 - Benyamin Limanto

11

toArray() 方法可将集合转换为数组,模型也会被转换为数组:

toArray() 方法将集合转换为普通 PHP 数组。如果集合中的值是 Eloquent 模型,则这些模型也会被转换为数组。

因此,我猜你可能做错了什么。如果需要更多帮助,请在问题中更新相关代码。

同时,只有 Eloquent 集合(模型)才有 toArray() 方法。

若要使用该方法,请使用 Eloquent:

$result = \App\User::all()->toArray();

$result = DB::select($sql)->toArray();$result = DB::select($sql)->toArray(); - aimme
异常'Symfony\Component\Debug\Exception\FatalErrorException',消息为'在数组上调用成员函数toArray()',位于... - Yevgeniy Afanasyev
@YevgeniyAfanasyev,我猜这就是aimee代码的答案。当然它不会起作用。请展示你的代码,我会告诉你如何将其转换为数组。 - Alexey Mezenin
我扩展了问题,我在那里放了一个例子。谢谢。 - Yevgeniy Afanasyev
我认为你没有完全阅读问题。你引用的文档甚至证明了你的答案是错误的。这个问题是关于stdClasses数组的。toArray函数并不会自动将它们转换为数组。你需要进行映射/转换。 - Nasso
显示剩余4条评论

4
对于使用illuminate/database 5.4的laravel/lumen 5.4:
$pdo = DB::getPdo();
$statement = $pdo->prepare($yourQuery);
$statement->setFetchMode(\PDO::FETCH_ASSOC);
$statement->execute();
$results = $statement->fetchAll();

或者监听 Illuminate\Database\Events\StatementPrepared 事件:Laravel 5.4 - 如何设置 PDO 获取模式?


3
你可以尝试这个。
DB::table('commune')->where('Commune','<>', 'ND')->orderBy('Commune')->get()->pluck('Commune');

1
您可以创建一个集合,以便使用toArray(),非常简单的方法:
$result = DB::table('users')->get();
$data = collect($result)->map(function($x){ return (array) $x; })->toArray(); 

采用了与array_map相同的概念,但没有额外的集合转换。恐怕您并没有做出很大的贡献。 - Yevgeniy Afanasyev

0
你可以这样做...
在顶部
use DB;
use PDO;

--------------------

DB::setFetchMode(PDO::FETCH_ASSOC); // Set the fetch mode as array

$result = DB::select('select * from users');

例如,现在您可以以这种方式获得结果。
$first_email = $result[0]['email'];

现在你可以更改为默认的获取模式。

DB::setFetchMode(PDO::FETCH_CLASS);

0
很高兴能够浏览这里的答案以了解原因。这是我最终确定的版本:
$users = collect($users) // turn the top level array into a collection
    ->map(fn($user) => (array) $user) // cast each object to an array
    ->toArray(); // convert top level collection back to an array

你之前有一个对象数组,现在你将会有一个数组的数组。请注意,这并不会递归地转换内部数组,但由于它只有一层深度,所以没问题。

0

试试这个

$result = DB::select($sql);
$arr = [];
foreach($result as $row)
{
    $arr[] = (array) $row;
}

这是错误的。我收到了:local.ERROR: 异常 'Symfony\Component\Debug\Exception\FatalErrorException',其消息为“在数组上调用成员函数get()”。 - Yevgeniy Afanasyev
更新 异常'ErrorException',消息为'call_user_func_array()期望参数1是一个有效的回调函数,类'Illuminate\Database\MySqlConnection'没有一个名为'selectRaw'的方法' - Yevgeniy Afanasyev
@huuuk,select 不仅接受列名:$users = DB::select('select * from users where active = ?', [1]); - 此外,你的例子并不起作用。为了让最后一个得到一些东西,你需要删除 ->get() - Alexey Mezenin
@AlexMezenin 对不起,我错了。你是对的。我对Eloquent有点困惑。 - huuuk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接