php - Having trouble understanding why my Closure wasn't working
I have a controller in laravel, AppExportController. In one of my functions on that controller, I iterate over many records and return a file download. I decided I wanted to create a little function so I could cache a certain thing, a Zone Name in this instance.
This was my first attempt at writing a function to cache the zone names (the getZoneName function obviously):
<?php
namespace App\Http\Controllers;
class AppExportController extends Controller {
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct() {
$this->middleware('auth');
$this->middleware('client.approved');
}
public function prices(Request $request) {
$user = Auth::user();
...
$zoneNameCache = [];
function getZoneName($zoneId) use (&$zoneNameCache) {
try {
if (!empty($zoneNameCache[$zoneId])) {
return $zoneNameCache[$zoneId];
} else {
$zone = ServiceZone::find($zoneId);
$zoneNameCache[$zoneId] = $zone->name;
return $zone->name;
}
} catch(Exception $e) {
return '';
}
};
$prices = []; // I actually do a database query here, don't worry about that
$records = [];
foreach($prices as $price) {
// output to $records here
$records[] = [
...
getZoneName($price->service_zone_id),
...
];
}
return response();
}
}
This was making that route 500 error, and I tracked it down to being for sure the closure aspect of the function -- when I took out theuse (&$zoneNameCache)
part, it worked (but didn't cache anything of course).
So I tried another thing -- assigning the function to a variable instead. And that worked! With the closure, and caching was working!
<?php
namespace App\Http\Controllers;
class AppExportController extends Controller {
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct() {
$this->middleware('auth');
$this->middleware('client.approved');
}
public function prices(Request $request) {
$user = Auth::user();
...
$zoneNameCache = [];
$getZoneName = function ($zoneId) use (&$zoneNameCache) {
try {
if (!empty($zoneNameCache[$zoneId])) {
return $zoneNameCache[$zoneId];
} else {
$zone = ServiceZone::find($zoneId);
$zoneNameCache[$zoneId] = $zone->name;
return $zone->name;
}
} catch(Exception $e) {
return '';
}
};
$prices = []; // I actually do a database query here, don't worry about that
$records = [];
foreach($prices as $price) {
// output to $records here
$records[] = [
...
$getZoneName($price->service_zone_id),
...
];
}
return response();
}
}
I don't know why the second one should work but not the first one. Can anyone shed light on this?
Answer
Solution:
Without assigning it to a variable, or returning it, it is not a closure.
This way you have function declaration, within another function or method in this case.
Which is not allowed, and therefore will give you a 500 for sure.
If you check your php error_log and probably your laravel log. It will tell you that.
If your do not want to assign it to a variable at that point, you could return it immediately
return function().......