Reputation: 1033
Whenever I run this code I get a:
PHP Fatal error: Cannot redeclare compare_distance()
The temporary solution appears to have been to duplicate findNearestLocation()
and give it a different name, so instead of calling findNearestLocation()
twice I call findNearestLocation1()
and findNearestLocation2()
.
I've tried unsetting the variables in the foreach loop but I can't quite figure out what I'm missing.
Upvotes: 0
Views: 3016
Reputation: 8945
My general understanding of the PHP language is, well, (shrug), that it has never been that sophisticated. It really doesn't know about "nested functions." It really only has two scopes for variables. And, so on.
(But then again, its designers never really set out to create "the most-popular web programming language in the world!" So it goes ...)
The initial compiler-error message: cannot re-declare {foobar},
was your first indication that the language didn't "grok" what you were trying to do.
Upvotes: 0
Reputation: 970
Of course, man )
Change:
function findNearestLocation($clientLocation) {
global $depotLocations;
$findDepot = $depotLocations;
$count = 0;
foreach ($findDepot as $row) {
$currentDepot = array($row['location_latitude'], $row['location_longitude']);
$findDepot[$count]['distance'] = distance($currentDepot,$clientLocation);
$count ++;
}
function compare_distance($a, $b) {
if ($a['distance'] == $b['distance']) return 0;
return ($a['distance'] < $b['distance']) ? -1 : 1;
}
usort($findDepot, 'compare_distance');
return $findDepot[0];
}
To:
function compare_distance($a, $b) {
if ($a['distance'] == $b['distance']) return 0;
return ($a['distance'] < $b['distance']) ? -1 : 1;
}
function findNearestLocation($clientLocation) {
global $depotLocations;
$findDepot = $depotLocations;
$count = 0;
foreach ($findDepot as $row) {
$currentDepot = array($row['location_latitude'], $row['location_longitude']);
$findDepot[$count]['distance'] = distance($currentDepot,$clientLocation);
$count ++;
}
usort($findDepot, compare_distance);
return $findDepot[0];
}
Or to (if you are using PHP7):
function findNearestLocation($clientLocation) {
global $depotLocations;
$findDepot = $depotLocations;
$count = 0;
foreach ($findDepot as $row) {
$currentDepot = array($row['location_latitude'], $row['location_longitude']);
$findDepot[$count]['distance'] = distance($currentDepot,$clientLocation);
$count ++;
}
usort(
$findDepot,
function ($a, $b) {return $a['distance'] <=> $b['distance'];}
);
return $findDepot[0];
}
Good luck!
Upvotes: 2
Reputation: 166359
Turns out the relatively simple solution was to not declare a function inside of a function.. once I moved compare_distance()
outside of the findNearestLocation()
function it works perfectly.
So now I understand the what, but I don't really understand the why.. what's the issue being created by declaring a function inside of a function?
Apologies if this seems an obvious issue, I'm fairly new to PHP still.
<?php
function findNearestLocation($clientLocation) {
global $depotLocations;
$findDepot = $depotLocations;
$count = 0;
foreach ($findDepot as $row) {
$currentDepot = array($row['location_latitude'], $row['location_longitude']);
$findDepot[$count]['distance'] = distance($currentDepot,$clientLocation);
$count ++;
}
function compare_distance($a, $b) {
if ($a['distance'] == $b['distance']) return 0;
return ($a['distance'] < $b['distance']) ? -1 : 1;
}
usort($findDepot, 'compare_distance1');
return $findDepot[0];
}
function distance($depot, $clientLocation) { // need to send two arrays with only longitude and latitude
list($lat1, $lon1) = $depot;
list($lat2, $lon2) = $clientLocation;
$theta = $lon1 - $lon2;
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
$dist = acos($dist);
$dist = rad2deg($dist);
$kilometres = $dist * 60 * 1.1515 * 1.609344;
return $kilometres;
}
// 4. ** These next two lines cause the error. If I comment out either of these lines, the code works fine and returns the expected result.
$finalPickup = findNearestLocation($pickupLocation);
$finalDropoff = findNearestLocation($dropoffLocation);
var_dump($finalPickup);
var_dump($finalDropoff);
?>
Source: @John Detlefs
Upvotes: 0