I have this function in a controller in laravel 10
public function change($id)
{
DB::beginTransaction();
try{
$current_period=Period::where('current',true)->first();
$current_period->current=false;
$current_period->save();
$new_period=Period::findOrFail($id);
$new_period->current=true;
$new_period->save();
//set person's memberSince and pay_mode to what is in the person_period pivot table
$persons=Person::all();
$persons->each(function ($person,$key){
global $new_period;
//dd($new_period->id);
$pivot=$person->periods()->where('period_id',$new_period->id)->first();
$person->memberSince=$pivot? $pivot['memberSince']:null;
$person->pay_mode=$pivot?$pivot['pay_mode']:null;
$$person->save();
});
DB::commit();
$result=[];
$ps=PersonResource::collection(Person::all());
array_push($result, $ps);
$pr=PeriodResource::collection(all());
array_push($result,$pr);
return $result;
}catch (Exception $e) {
DB::rollBack();
throw $e;
}
}
it returns an error
message ‘Attempt to read property "id" on null’
on the line just behind the presently commented line
//dd($new_period->id)
when I uncomment the line it returns the same error.
When I place the uncommented line outside the each loop, it returns the correct id of $new_period
confirming that outside the each loop the $new_period
exists.
What am I missing here?
2
Answers
PHP’s anonymous functions require you to explicitly state which variables it has access to. As you’re not doing that,
$new_period
is not defined in the->each()
callback. You can solve this using theuse
-keyword as follows:See also example #3 from the documentation.
You need to use
use()
in your closure to expose outer variable. In this case:use ($new_period)
:Check the 3rd example in this PHP documentation page.