views:

82

answers:

4

Hi,

I asked a related question before I lost my login id - http://stackoverflow.com/questions/3723748/php-version-5-2-14-parse-error-syntax-error-unexpected-t-function-expecting - but this is the "entire" problem.

I'm having a hard time figuring out how to convert this function (got from somewhere on SO) to work with PHP 5.2.14 (which as folks informed me - does not support anonymous functions). I tried a few permutations of changing the code to make it work with array_map() but I cant wrap my head around how everything works!

The entire function is pasted below, but only the areas pointed out are the ones that PHP 5.2.14 complains about..

function convertGeneralAvailabilityTime($date,$from_timezone,$from_timebegin, $from_timeend, $to_timezone)
{

$tz1 = new DateTimezone($from_timezone);

$datetime1 = new DateTime("$date $from_timebegin", $tz1);
$datetime2 = new DateTime("$date $from_timeend", $tz1);

$convertedAvail = array(
    array($datetime1, $datetime2),
);


$tz2 = new DateTimezone($to_timezone);
//convert periods:

// ISSUE_START

$times = array_map(
    function (array $p) use ($tz2) {
       $res = array();
       foreach ($p as $d) {
           $res[] = $d->setTimezone($tz2);
       }
       return $res;
    },
    $convertedAvail
);

// ISSUE_END

$res = array();
foreach ($times as $t) {
    $t1 = reset($t);
    $t2 = next($t);
    if ($t1->format("d") == $t2->format("d")) {
        $res[$t1->format("l")][] = $t1->format("g:i a") . " to ".
            $t2->format("g:i a");
    }
    else {
        $res[$t1->format("l")][] = $t1->format("g:i a") . " to 11:59 pm";
        $res[$t2->format("l")][] = "12:00 am to ". $t2->format("g:i a");
    }
}

return $res;
}
A: 

Instead of using the function inline in the array_map() call, you can define it outside regularly with a name, and feed its name to array_map(). You can just global $tz2 inside that function to have access to that value.

function set_timezone_callback($p) {
    global $tz2;
    $res = array();
    foreach ($p as $d) {
        $res[] = $d->setTimezone($tz2);
    }
    return $res;
}

$times = array_map('set_timezone_callback', $convertedAvail);

refactoring suggestion based on your code assuming it works, didn't test.

kemp
Hi... i would like to avoid having tz2 as a global variable... is it possible to rejig your function to fit that?
matt_tm
+1  A: 

If you are okay with $converedAvail to be modified, then you could use array_walk and pass user defined data:

function convertTimezone(array &$p, $key, $tz2) {
    foreach ($p as &$d) {
        $d = $d->setTimezone($tz2);
    }
}

array_walk($convertedAvail, 'convertTimezone', $tz2);

I haven't tested it. But if your previous code worked on 5.3, then this one should work on 5.2.

nikic
hi nikic - that didnt work, nothing got displayed
matt_tm
@matt_tm, the example is supposed to give you new ideas, it is not something you can copy-paste in the code and then it works. You are expected to understand what you are working on.
Sjoerd
Thanks Sjoerd - but i'm stuck at the implementation stage, not at the ideation part. how to get it to work _is_ the question....
matt_tm
Hi nikic - this looks really promising, but i'm trying to understand how this would give the $times variable what it needs...
matt_tm
This modifies the `$convertedAvail` variable and doesn't create a `$times` var. If you need that you should put a `$times = $convertedAvail;` before the `array_walk` and replace the `$convertedAvail` in the `array_walk` function call with `$times`.
nikic
matt_tm
nikic
With it - it didnt work. Without it - it did.
matt_tm
A: 

array_map simply executes the anonymous function for every element of $convertedAvail. Instead of array_map, you can loop over the elements using foreach and call setTimezone()

foreach ($convertedAvail as $cKey => $dateArray)
{
    foreach ($dateArray as $dKey => $date)
    {
        $convertedAvail[$cKey][$dKey]->setTimezone($tz2);
    }
}
Sjoerd
i dont think that would work - convertedAvail isnt a key->value array. have a look at the code in the OP.
matt_tm
All arrays are key->value arrays. If you do not explicitly define a key, a numeric key will be used automatically.
Sjoerd
how does this affect the times variable?
matt_tm
A: 

Well, as mentioned PHP < 5.3 does not support anonymous functions, therefore you have to define some global function.

Common solution:

# PHP 5.3+

$array = array_map(function() {
    return /* do sth */;
}, $array);

# PHP < 5.3

function abcMyFunction() {
    return /* do sth */;
}

$array = array_map('abcMyFunction', $array);

Applying the above code to your, should be easy now.

Using create_function():

PHP <5.3 supports some kind of anonymous functions - you can define them using create_function(). Although it doesn't litter your global namespace it's so unreadable and hard to maintain that I wouldn't suggest to use that solution.

Crozin
this is an isolated function and no one's really gonna touch it (its convulated as it is!)... but i dont want to have global functions - can i not encapsulate all that _within_ the one function itself?
matt_tm