I'm trying passing an Laravel Eloquent collection into a function, inside the function I'm doing some collection manipulation.
If I do something like map
method on the collection, it will also alter the underlying models for the outer collection variable.
How can I passing collection by value into a function? I tried clone
and ->collect()
method, but seems not work.
Thanks.
$users = User::where('type', 1)->get();
$this->doSomething($users);
// or
$this->doSomething(clone $users);
// or
$this->doSomething($users->collect());
foreach($users as $user)
{
$user->location; // has been modified in 'doSomething' function.
}
private function doSomething(Collection $users)
{
$mapUsers = $users->map(function ($user) {
$user->location = 'some value';
return $user;
});
// using $mapUsers...
}
Was going to leave this as a comment but it was getting too verbose. When you clone the collection, the references inside remain the same.
You have two options: if you need to work with actual User
objects, do this:
$users = User::where('type', 1)->get();
$this->doSomething($users);
foreach($users as $user) {
echo $user->location;
}
private function doSomething(Collection $users)
{
$mapUsers = $users->map(function (User $user) {
$u = clone $user;
$u->location = 'some value';
return $u;
});
// using $mapUsers...
}
Or less complicated, if you just need the values, would be to pass an array. The toArray()
method is recursive, so it turns the inside objects into arrays as well:
$users = User::where('type', 1)->get();
$this->doSomething($users->toArray());
foreach($users as $user) {
echo $user->location;
}
private function doSomething(array $users)
{
$mapUsers = collect($users)->map(function (array $user) {
$user['location'] = 'some value';
return $user;
});
// using $mapUsers...
}