skip to Main Content

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


  1. 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 the use-keyword as follows:

    $persons->each(function ($person, $key) use ($new_period) {
        // Your existing code
    });
    

    See also example #3 from the documentation.

    Login or Signup to reply.
  2. You need to use use() in your closure to expose outer variable. In this case: use ($new_period):

    $persons->each(function ($person,$key) use ($new_period) {
        $pivot=$person->periods()->where('period_id',$new_period->id)->first();
        // the rest of your handler...
    });
    

    Check the 3rd example in this PHP documentation page.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search