Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

vipin93's avatar
Level 13

Invalid argument supplied for foreach()?

I'm try to display message for due fee month.Those student who not submitted fee last month then show message in his account please pay fee u have not submitted fee "name of the month.

here is controller


public function fee($reg_no = null)
   {

     $dt = Carbon::now()->month;

     $s = Student::where('reg_no', $reg_no)->with('subscriptions','courses.fees')->first();

      $fees = Fee::get();

      $messages = array();
     foreach ($s->subcriptions as $subcription) {
    if ($subcription->tution_fee != null) {
        $month = $subcription->month->month(); 
        if ($month == 1) {$month = 'January';}
        if ($month == 2) {$month = 'February';}
        if ($month == 3) {$month = 'March';}
        if ($month == 4) {$month = 'April';}
        if ($month == 5) {$month = 'May';}
        if ($month == 6) {$month = 'June';}
        if ($month == 7) {$month = 'July';}
        if ($month == 8) {$month = 'Agust';}
        if ($month == 9) {$month = 'September';}
        if ($month == 10) {$month = 'October';}
        if ($month == 11) {$month = 'Navember';}
        if ($month == 12) {$month = 'December';}           
        $message = 'Your fee are due for '.$month;
        array_push($messages, $message);
       }
     }

     return view('fee.fee_form',compact('s','fees','dt','messages'));
   }

and here is errors

Whoops, looks like something went wrong.

1/1
ErrorException in SubscriptionController.php line 38:
Invalid argument supplied for foreach()
in SubscriptionController.php line 38
at HandleExceptions->handleError(2, 'Invalid argument supplied for foreach()', 'C:\\laragon\\www\\gpschool\\app\\Http\\Controllers\\SubscriptionController.php', 38, array('reg_no' => 'GRN2017846623', 'dt' => 2, 's' => object(Student), 'fees' => object(Collection), 'messages' => array())) in SubscriptionController.php line 38
at SubscriptionController->fee('GRN2017846623')
at call_user_func_array(array(object(SubscriptionController), 'fee'), array('reg_no' => 'GRN2017846623')) in Controller.php line 55
at Controller->callAction('fee', array('reg_no' => 'GRN2017846623')) in ControllerDispatcher.php line 44
at ControllerDispatcher->dispatch(object(Route), object(SubscriptionController), 'fee') in Route.php line 203
at Route->runController() in Route.php line 160
at Route->run() in Router.php line 559
at Router->Illuminate\Routing\{closure}(object(Request)) in Pipeline.php line 30
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in RevalidateBackHistory.php line 15
at RevalidateBackHistory->handle(object(Request), object(Closure)) in Pipeline.php line 148
at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 53
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in SubstituteBindings.php line 41
at SubstituteBindings->handle(object(Request), object(Closure)) in Pipeline.php line 148
at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 53
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in Authenticate.php line 43
at Authenticate->handle(object(Request), object(Closure)) in Pipeline.php line 148
at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php lin

here is the full discussion http://stackoverflow.com/questions/42119198/how-to-retrieve-due-fee-month-wise-student/42304685?noredirect=1#comment71765168_42304685

0 likes
34 replies
tykus's avatar

You spelled subscriptions wrong in the foreach statement (several times)... and...

$month = DateTime::createFromFormat('m', $month)->format('F'); 
vipin93's avatar
Level 13

@tykus my array is showing empty it should be i think should show message

Your fee are due for January.
Your fee are due for February.
Your fee are due for march

tykus's avatar

Your code above has also misspelled tuition_fee - Laravel returns null if this is the case, so the if block will never run. This collection pipeline looks better in my opinion:

$messages = $s->subscriptions->filter(function ($subscription) {
    return $subcription->tuition_fee !== null;
})->map(function ($subscription) {
    $month = DateTime::createFromFormat('m', $month)->format('F'); 
    return "Your fee are due for {$month}";
});
tykus's avatar

dd($s->subscriptions) before the Collection pipeline - just to make sure that there are tuition_fees.

vipin93's avatar
Level 13

@tykus same

dd($s->subscriptions);

      $messages = $s->subscriptions->filter(function ($subscription) {
    return $subcription->tuition_fee !== null;
})->map(function ($subscription) {
    $month = DateTime::createFromFormat('m', $month)->format('F'); 
    return "Your fee are due for {$month}";
});

Collection {#487 ▼
  #items: []
}
tykus's avatar

So that student has no subscriptions...

vipin93's avatar
Level 13

@tykus Undefined variable: month on line 43

$month = \DateTime::createFromFormat('m', $month)->format('F');
ErrorException in SubscriptionController.php line 43:
Undefined variable: month
in SubscriptionController.php line 43
at HandleExceptions->handleError(8, 'Undefined variable: month', 'C:\\laragon\\www\\gpschool\\app\\Http\\Controllers\\SubscriptionController.php', 43, array('subscription' => object(Subscription))) in SubscriptionController.php line 43
at SubscriptionController->App\Http\Controllers\{closure}(object(Subscription), 0)
at array_map(object(Closure), array(object(Subscription)), array(0)) in Collection.php line 652
at Collection->map(object(Closure)) in Collection.php line 130
at Collection->map(object(Closure)) in SubscriptionController.php line 45
at SubscriptionController->fee('GRN2017179240')
at call_user_func_array(array(object(SubscriptionController), 'fee'), array('reg_no' => 'GRN2017179240')) in Controller.php line 55
at Controller->callAction('fee', array('reg_no' => 'GRN2017179240')) in ControllerDispatcher.php line 44
at ControllerDispatcher->dispatch(object(Route), object(SubscriptionController), 'fee') in Route.php line 203
at Route->runController() in Route.php line 160
at Route->run() in Router.php line 559
at Router->Illuminate\Routing\{closure}(objec

tykus's avatar

Assuming this worked for you before $subscription->month->month():

$messages = $s->subscriptions->filter(function ($subscription) {
    return $subcription->tuition_fee !== null;
})->map(function ($subscription) {
    
    $month = DateTime::createFromFormat('m', $subscription->month->month())->format('F'); 
    return "Your fee are due for {$month}";
});
vipin93's avatar
Level 13

@tykus

Missing argument 1 for Carbon\Carbon::month(), called in C:\laragon\www\gpschool\app\Http\Controllers\SubscriptionController.php on line 43 and defined
tykus's avatar

Dude, that was your code (which obviously didn't work before... What is stored in $subscription->month?

vipin93's avatar
Level 13

@tykus

{{ Form::selectMonth('month',  null, ['placeholder' => '---Select Month','class' => 'form-control','required'=> ' "" '  ]) }}

my Subscription model

 protected $fillable = [
        'tution_fee','development_fee','other_fee','month','remarks','late_fee','course_id'
    ];

     protected $dates = ['month'];

   public function setMonthAttribute($value)
    {
         //dd($value);
        $this->attributes['month'] = Carbon::createFromFormat('m',$value);
    }
tykus's avatar

So it is a number in the range 1 - 12 then?

$messages = $s->subscriptions->filter(function ($subscription) {
    return $subcription->tuition_fee !== null;
})->map(function ($subscription) {
    
    $month = DateTime::createFromFormat('m', $subscription->month)->format('F'); 
    return "Your fee are due for {$month}";
});
vipin93's avatar
Level 13

@tykus FatalThrowableError in SubscriptionController.php line 43: Call to a member function format() on boolean

tykus's avatar

So month is a Carbon instance - a full date object?? Cryptic!

$messages = $s->subscriptions->filter(function ($subscription) {
    return $subcription->tuition_fee !== null;
})->map(function ($subscription) {
    
    $month = DateTime::createFromFormat('m', $subscription->month->month)->format('F'); 
    return "Your fee are due for {$month}";
});
vipin93's avatar
Level 13

@tykus its returning

Collection {#497 ▼
  #items: array:1 [▼
    0 => "Your fee are due for January"
  ]
}

when i submitted the fee of january month instead of february (<=current month) because he not submitted the month of february . here is i want message if student not submitted fee of the all month(<= current month) its so all month name like (Your fee are due for January, Your fee are due for february ....) if he submitted the month of january then no message for january month only (Your fee are due for february )

tykus's avatar

This means that for January the following is true - this was your original code:

$subcription->tuition_fee !== null

Should this then by reversed so that only months that do not have a tuition_fee are returned?

$subcription->tuition_fee == null

Do you understand what the collection pipeline is doing?

vipin93's avatar
Level 13

@tykus i changed to $subcription->tuition_fee == null but no luck

Collection {#497 ▼
  #items: []
}
tykus's avatar

@vipin93 can share a dump of the collection returned by dd($s->subscriptions and describe in plain language what you want to do.

vipin93's avatar
Level 13

@tykus here as u can see this student(student_id=7) submitted fee month of january(1) and february(2), suppose current month is july(7) if this student not submitted the month of march(3),april(4) june(5) and so on then i want show message in his/her(student_id=7) that [Your fee are due for march., Your fee are due for april. Your fee are due for may. Your fee are due for june. Your fee are due for july].(limit to current month).

here is dd($s->subscriptions);

Collection {#494 ▼
  #items: array:2 [▼
    0 => Subscription {#504 ▼
      #fillable: array:7 [▼
        0 => "tution_fee"
        1 => "development_fee"
        2 => "other_fee"
        3 => "month"
        4 => "remarks"
        5 => "late_fee"
        6 => "course_id"
      ]
      #dates: array:1 [▼
        0 => "month"
      ]
      #connection: null
      #table: null
      #primaryKey: "id"
      #keyType: "int"
      +incrementing: true
      #with: []
      #perPage: 15
      +exists: true
      +wasRecentlyCreated: false
      #attributes: array:11 [▼
        "id" => 4
        "student_id" => 7
        "course_id" => 13
        "other_fee" => null
        "tution_fee" => "455"
        "late_fee" => null
        "development_fee" => null
        "remarks" => null
        "month" => "2017-02-18"
        "created_at" => "2017-02-18 22:25:36"
        "updated_at" => "2017-02-18 22:25:36"
      ]
      #original: array:11 [▼
        "id" => 4
        "student_id" => 7
        "course_id" => 13
        "other_fee" => null
        "tution_fee" => "455"
        "late_fee" => null
        "development_fee" => null
        "remarks" => null
        "month" => "2017-02-18"
        "created_at" => "2017-02-18 22:25:36"
        "updated_at" => "2017-02-18 22:25:36"
      ]
      #casts: []
      #dateFormat: null
      #appends: []
      #events: []
      #observables: []
      #relations: []
      #touches: []
      +timestamps: true
      #hidden: []
      #visible: []
      #guarded: array:1 [▼
        0 => "*"
      ]
    }
    1 => Subscription {#505 ▼
      #fillable: array:7 [▼
        0 => "tution_fee"
        1 => "development_fee"
        2 => "other_fee"
        3 => "month"
        4 => "remarks"
        5 => "late_fee"
        6 => "course_id"
      ]
      #dates: array:1 [▼
        0 => "month"
      ]
      #connection: null
      #table: null
      #primaryKey: "id"
      #keyType: "int"
      +incrementing: true
      #with: []
      #perPage: 15
      +exists: true
      +wasRecentlyCreated: false
      #attributes: array:11 [▼
        "id" => 3
        "student_id" => 7
        "course_id" => 13
        "other_fee" => null
        "tution_fee" => "455"
        "late_fee" => null
        "development_fee" => null
        "remarks" => null
        "month" => "2017-01-18"
        "created_at" => "2017-02-18 02:45:14"
        "updated_at" => "2017-02-18 02:45:14"
      ]
      #original: array:11 [▼
        "id" => 3
        "student_id" => 7
        "course_id" => 13
        "other_fee" => null
        "tution_fee" => "455"
        "late_fee" => null
        "development_fee" => null
        "remarks" => null
        "month" => "2017-01-18"
        "created_at" => "2017-02-18 02:45:14"
        "updated_at" => "2017-02-18 02:45:14"
      ]
      #casts: []
      #dateFormat: null
      #appends: []
      #events: []
      #observables: []
      #relations: []
      #touches: []
      +timestamps: true
      #hidden: []
      #visible: []
      #guarded: array:1 [▼
        0 => "*"
      ]
    }
  ]
}
tykus's avatar

You don't have any Subscription instances for the missing months, so testing for a missing tuition_fee is moot - this changes everything:

// Create a Collection of student subscriptions keyed by month name:
$subscriptions = $s->subscriptions->keyBy(function ($subscription) {
    return $subscription->month->format('F');
});


// Get all the months this year up to the current month
// and iterate over the $months testing for missing subscriptio month or subscription month missing tuition fee creating the array of messages
$messages = collect(range(1, date('n'))->map(function($monthNum) {
    return Carbon\Carbon::createFromFormat('m', $monthNum)->format('F');
})->reject(function ($month) use ($subscriptions) {
    return $subscriptions->keys()->contains($month) && $subscription[$month]->tuition_fees !== 0;
})->map(function($missingMonth) {
    return "Your fees are due for $missingMonth";
});
tykus's avatar

@vipin93 great!!! Try to describe your problem a little better the next time and we won't go around the houses to get to an answer.

vipin93's avatar
Level 13

@tykus what if some student not submitted the fee of december(previous year (2016)) month and current month is january(2017) so i think here may be its bu. so how to deal with this problem

tykus's avatar
tykus
Best Answer
Level 104

Sorry @vipin93 small typo

// change 
range(1, 7)
// to
range(1, date('n')) // date('n') will always give you the current month

If your time range spans two years, then you will need to change things slightly.

$subscriptions = $s->subscriptions->keyBy(function ($subscription) {
    return $subscription->month->format('F Y');
});

Now, you will also need to handle the fact that the range(1, n) I gave you above is no longer useful; you can set up a DatePeriod to dynamically generate the months:

$start = Carbon\Carbon::parse('September last year'); // or whatever month the academic year starts
$now = Carbon\Carbon::now();
$interval = new DateInterval('P1M');
$months = new DatePeriod($start, $interval, $now);

$messages = collect($months)->map(function ($month) {
    return $month->format('F Y');
})->reject(function ($month) use ($subscriptions) {
    return $subscriptions->keys()->contains($month) && $subscription[$month]->tuition_fees !== 0;
})->map(function($missingMonth) {
    return "Your fees are due for {$missingMonth->format('F')}";
});
vipin93's avatar
Level 13

@tykus

FatalThrowableError in SubscriptionController.php line 104:
Call to a member function format() on string
in SubscriptionController.php line 104
at SubscriptionController->App\Http\Controllers\{closure}('September 2016', 0)
at array_map(object(Closure), array('September 2016', 'October 2016', 'November 2016', 'December 2016', 'January 2017', 'February 2017'), array(0, 1, 2, 3, 4, 5)) in Collection.php line 652
at Collection->map(object(Closure)) in SubscriptionController.php line 105
at SubscriptionController->fee('GRN2017179240')
at call_user_func_array(array(object(SubscriptionController), 'fee'), array('reg_no' => 'GRN2017179240')) in Controller.php line 55
at Controller->callAction('fee', array('reg_no' => 'GRN2017179240')) in ControllerDispatcher.php line 44
at ControllerDispatcher->dispatch(object(Route), object(SubscriptionController), 'fee') in Route.php line 203
at Route->runController() in Route.php line 160
at Route->run() in Router.php line 559
at Router->Illuminate\Routing\{closure}(object(Request)) in Pipeline.php line 30
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in RevalidateBackHistory.php line 15
at RevalidateBackHistory->handle(object(Request), object(Closure)) in Pipeline.php line 148
tykus's avatar

Do you debug code ever? Which one is line 104, probably this one:

return "Your fees are due for {$missingMonth->format('F')}";

Change it to

return "Your fees are due for {$missingMonth}"; // February 2017

or, if you only want the month name only, this is more compact:

$messages = collect($months)->reject(function ($month) use ($subscriptions) {
    return $subscriptions->keys()->contains($month->format('F Y')) && $subscription[$month->format('F Y')]->tuition_fees !== 0;
})->map(function($missingMonth) {
    return "Your fees are due for {$missingMonth->format('F')}";
});
vipin93's avatar
Level 13

@tykus return "Your fees are due for {$missingMonth->format('F')}";

tykus's avatar

See updated answer above

1 like
Next

Please or to participate in this conversation.