我一直在檢討Laravel類別的文檔和API,但似乎並沒有找到我在尋找:從Laravel收集獲取,只有特定的屬性
我想檢索與模型的數組來自集合的數據,但只獲取指定的屬性。
I.e.類似Users::toArray('id','name','email')
,其中集合實際上包含用戶的所有屬性,因爲它們在其他地方使用,但在此特定位置我需要一個包含userdata的數組,並且只包含指定的屬性。
Laravel似乎沒有這方面的幫手嗎? - 我怎樣才能做到這一點最簡單的方法?
我一直在檢討Laravel類別的文檔和API,但似乎並沒有找到我在尋找:從Laravel收集獲取,只有特定的屬性
我想檢索與模型的數組來自集合的數據,但只獲取指定的屬性。
I.e.類似Users::toArray('id','name','email')
,其中集合實際上包含用戶的所有屬性,因爲它們在其他地方使用,但在此特定位置我需要一個包含userdata的數組,並且只包含指定的屬性。
Laravel似乎沒有這方面的幫手嗎? - 我怎樣才能做到這一點最簡單的方法?
您可以使用現有的Collection
方法的組合來完成此操作。起初可能有點難,但應該很容易分解。
// get your main collection with all the attributes...
$users = Users::get();
// build your second collection with a subset of attributes. this new
// collection will be a collection of plain arrays, not Users models.
$subset = $users->map(function ($user) {
return collect($user->toArray())
->only(['id', 'name', 'email'])
->all();
});
說明
首先,map()
方法基本上只是通過Collection
迭代,並通過在Collection
每個項目在回調通過。從每個回調調用返回的值將生成由map()
方法生成的新的Collection
。
collect($user->toArray())
只是在Users
屬性中構建了一個新的臨時Collection
。
->only(['id', 'name', 'email'])
將臨時Collection
減少到僅指定的那些屬性。
->all()
將暫時的Collection
變成一個普通數組。
把它放在一起,你會得到「對於用戶集合中的每個用戶,返回一個只包含id,name和email屬性的數組。
您需要定義$hidden
和$visible
屬性。他們將被設置爲全局(這意味着總是返回來自$visible
數組的所有屬性)。
使用方法makeVisible($attribute)
和makeHidden($attribute)
您可以動態更改隱藏和可見屬性。更多:Eloquent: Serialization -> Temporarily Modifying Property Visibility
我不希望這是全球性的,但選擇要動態從集合中提取的屬性。 – preyz
使用User::get(['id', 'name', 'email'])
,它會回報你一個集合與指定的列,如果你想成爲一個數組,只需使用toArray()
的get()
方法,像這樣經過:
User::get(['id', 'name', 'email'])->toArray()
大多數情況下,您不需要將集合轉換爲數組,因爲集合實際上是類固醇上的數組,並且您有易於使用的方法來操作集合。
該集合已由先前的查詢創建,其中需要更多屬性。因此我需要生成一個只有特定屬性的數據數組。 – preyz
你可以讓你的查詢動態地傳遞一列數組來返回,或者你可以做另一個' - > get(['id','email','name'])'',它不會重新查詢數據庫,但它將僅返回一個僅包含選定值的新集合。諸如pluck/lists,get,first等方法在查詢構建器類和集合類中都具有相同的名稱。 – Ruffles
荷葉邊,在Laravel 5.3中不起作用。 - 查詢生成器「get」方法事實上確實需要列,但它也執行另一個查詢。該集合的「get」方法可以通過集合中的鍵提取特定的模型,這不是我在這之後所做的。 – preyz
我現在已經想出了一個自己的解決這一:
1中創建的一般功能,以提取從陣列
從關聯數組下面僅提取特定屬性的功能的特定屬性,或者關聯數組的數組(最後是在Laravel中執行$ collection-> toArray()時得到的數組)。
它可以像這樣使用:
$data = array_extract($collection->toArray(), ['id','url']);
我使用了以下功能:
function array_is_assoc($array)
{
return is_array($array) && array_diff_key($array, array_keys(array_keys($array)));
}
function array_extract($array, $attributes)
{
$data = [];
if (array_is_assoc($array))
{
foreach ($attributes as $attribute)
{
$data[ $attribute ] = $array[ $attribute ];
}
}
else
{
foreach ($array as $key => $values)
{
$data[ $key ] = [];
foreach ($attributes as $attribute)
{
$data[ $key ][ $attribute ] = $values[ $attribute ];
}
}
}
return $data;
}
這種解決方案並不注重性能的影響通過在大型數據集的集合循環。
2.通過自定義集合執行上述我Laravel
因爲我想能夠簡單地做$collection->extract('id','url');
任何集合對象,我實現了一個自定義集合類。
首先我創建了一個通用模型,它擴展了Eloquent模型,但使用了不同的集合類。你所有的模型都需要擴展這個自定義模型,而不是擴展模型。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model as EloquentModel;
use Lib\Collection;
class Model extends EloquentModel
{
public function newCollection(array $models = [])
{
return new Collection($models);
}
}
?>
其次我創建了下面的自定義集合類:從
<?php
namespace App\Models;
class Article extends Model
{
...
現在的功能沒有:
<?php
namespace Lib;
use Illuminate\Support\Collection as EloquentCollection;
class Collection extends EloquentCollection
{
public function extract()
{
$attributes = func_get_args();
return array_extract($this->toArray(), $attributes);
}
}
?>
最後,所有車型應該再擴展您的自定義模型,而不是像這樣。上面的1被整齊地用於收集以使$collection->extract()
方法可用。
查看有關擴展集合的Laravel文檔:https://laravel.com/docs/5.5/collections#extending-collections –
這似乎工作,但不知道它是否優化的性能與否。
$request->user()->get(['id'])->groupBy('id')->keys()->all();
輸出:
array:2 [
0 => 4
1 => 1
]
我假設你有設置你的數據庫連接,並建立查詢中的一切控制器秩序。
你可以做這個... :)
$user_details = User::get(['id','username','email']);
dd($user_details);
我有,我需要從一個大陣選擇值的類似的問題,但我想結果集合只包含一個單一的值值。
pluck()
可以用於此目的(如果只有1次關鍵項目是必需的)
你也可以使用reduce()
。類似這樣的減少:
$result = $items->reduce(function($carry, $item) {
return $carry->push($item->getCode());
}, collect());
謝謝!我已經將此標記爲公認的答案,因爲它具有現有Laravel功能的魅力。 - 現在,可以通過自定義集合類將其提供給集合,就像我在替代解決方案中描述的那樣。 – preyz