John Detlefs
John Detlefs

Reputation: 1033

Can call function twice?

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

Answers (3)

Mike Robinson
Mike Robinson

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

Leonid Zakharov
Leonid Zakharov

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

kenorb
kenorb

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

Related Questions