我刚写了一个可怕的PHP函数,我需要一些帮助(elseif chain - switch?)

Ale*_*Mcp 9 php optimization

我正在建立一个网站,根据它的时间确定数组的值.我写了这个糟糕的(功能)脚本,我想知道我是否可以让它更简洁.我开始使用case/switch语句,但是在使用多个条件时遇到了麻烦.这是肮脏的行为:

if ($now < november 18th) {
    $array_to_use = $home;
}
elseif (november 18th < $now && $now < november 21st ) {
    $array_to_use = $driving;
}
elseif (november 21st < $now && $now < november 22nd) {
    $array_to_use = $flying;
}
...
...
...
elseif (february 1st < $now) {
    $array_to_use = $arrived;
}
else {
    $array_to_use = $default;
}
Run Code Online (Sandbox Code Playgroud)

时间表实际上更复杂,其中有13个elseif陈述.有人可以确认我只是编码器的阻塞,有更好的方法吗?

编辑:我将Unix时间戳更改为粗略的实际时间,因此更容易理解我在做什么(希望如此)

编辑2:请原谅当前损坏的Javascript时钟,但这是我正在处理的网站:

时间表.

每个阵列都基于我的位置,根据它的时间有15个"它们当前".这是一个具有已知开始/结束时间的小问题域,因此灵活性不是关键,只需将其全部写入.您可以看到时间是如何连续的,并且一次只需要选择一个字符串数组.

Zak*_*Zak 13

首先,请请取出您的硬编码并将它们放入常数中.

$FLIGHT_START_TIME = 1258956001;
$FLIGHT_END_TIME   = 1260511201;
Run Code Online (Sandbox Code Playgroud)

其次,我会为每个条件制作迷你函数:

function isFlying($time)
{
    return ( $FLIGHT_START_TIME < $time && $time < $FLIGHT_END_TIME );
}
Run Code Online (Sandbox Code Playgroud)

第三,拿出你的整套条件,并把它放到一个函数中来获取你当前的状态,并替换你的函数调用:

function getStateArrayForTime($time)
{

   if (isDriving($time)
   {
       return $driving;
   }
   if ( isFlying($time) )
   {
        return $flying;
   }
...etc
}
Run Code Online (Sandbox Code Playgroud)

最后,用单个函数调用替换代码的整个内联部分:

$currentState = getStateArrayForTime($now);
Run Code Online (Sandbox Code Playgroud)

正如其他海报也评论过的那样,此时你可以使用数据表驱动函数来返回状态,如果你知道只有开始和结束时间将是状态参数:

所以用以下代码替换getStateArrayForTime的实现:

function getStateArrayForTime ($time)
{
// 
$states = array (
    array("startTime" => 1258956001, "endTime" => 1260511201, "state" => $flying),
    array("startTime" => 1260511201, "endTime" => 1260517000, "state" => $driving),
..etc...
);
    foreach($states as $checkStateArray)
    {
        if($checkStateArray['startTime'] < $time && $time < $checkStateArray['endTime'])
        {
            return $checkStateArray['state'];
        }
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

最后,有些人可能会问"为什么按此顺序做事?" 除了在应用程序中,我根本不能要求信用,但Martin Fowler有一本名为"Refactoring"的好书解释了为什么你一步一步地清理代码,并在每一步测试,然后最后替换那些没有意义的功能批发,一直测试它们在功能上是等效的.

  • 问题在于,如果你结束200多个状态,你还有200多个函数(他已经有13个函数了).添加更多状态不应该增加代码,只是增加一些(最好是外部)数据块. (2认同)

Ry4*_*ase 7

这可能是矫枉过正,但我​​会做这样的事情,这样我就可以将所有时间范围放在一个清晰的位置:

@timeWindows = ({ start -> 0, end -> 1258783201, array -> $home },
                ... ,
                {start -> 1260511201, end -> MAXVAL, array -> $arrived});
Run Code Online (Sandbox Code Playgroud)

然后像一个循环

$array_to_use = $default;

foreach (my $window in @timeWindows) {
   if (($now > $window->start) && ($now < $window->end)) {
       $array_to_use = $window->array;
       last;
   }
}
Run Code Online (Sandbox Code Playgroud)

对不起它是Perl,我不懂PHP,但我想它类似.