PHP优化一个很长的开关案例声明

时间:2012-11-19 05:16:34

标签: php arrays caching optimization switch-statement

请查看以下代码

function GetAreaName($AreaCode)
{
  switch ($AreaCode) 
  {
    case 201: return 'New Jersey';
    case 202: return 'Washington';
    // this goes on till
    case 999: return '';
  }
}

让我们说如果AreaCode是998那么它将不得不经历这么多案件! 我们怎样才能优化这个功能? (使用数据库。)

我正在考虑构建一个数组并对其进行二进制搜索?但是这意味着每次调用该函数时都会重建数组?我们如何构建一次数组,缓存它并在每次调用此函数时重复使用?

4 个答案:

答案 0 :(得分:7)

为什么不使用哈希表?

class Area {

private $areaCodes = array(
            201 => 'New Jersey',
            202 => 'Washington',
            // this goes on till
            999 => '';
        );

    function getStateByAreaCode ($areaCode) {

        if (array_key_exists($areaCode, $this->areaCodes)) {
           return $this->areaCodes[$areaCode];
        } else {
           return false;
        }

    }
}

这样称呼:

$area = new Area();
$city = $area->getStateByAreaCode(303);

只需将您的课程保存在文件中,并在需要时将其包含在内。

您询问如何防止每个请求创建数组: 把它放在课堂上你至少保持干净。技术上仍然会在每个请求中创建,但除非您的阵列很大(比美国的区域代码大),否则不会造成性能问题。如果您担心每次有请求时都要构建数组,那么请查看代码优化器,如APC或Zend Optimizer。这基本上采用PHP在运行时生成的字节代码并缓存它。

答案 1 :(得分:3)

听起来你应该将它存储在数据库中。

但是如果你不能这样做,要么将它抽象成某种配置文件并将其存储在某种持久化对象中,要么只使用静态变量:

function foo($key) {
    static $cache = array(1 => 'abc', 2 => 'def', 3 => 'ghi');
    if (array_key_exists($key, $cache)) {
        return $cache[$key];
    } else {
        //Somehow signal an error (throw an exception, return boolean false, or something)
    }
}

在上文中,$cache只存在一次。 (如果您知道值永远不会是null,则可以使用isset代替array_key_exists。)

虽然更改数据需要您编辑代码,但这不是很灵活。您通常希望将数据和代码分离。

这可能意味着将其存储在某种文件(json,xml,php,等等)中,并将其加载到您只创建一次的某种结构中。然后,您可以将该对象或数组传递到需要的任何位置。 (或者,如果你想成为hacky,你可以使用静态类。但我建议不要这样做。)

答案 2 :(得分:2)

开关条件仅评估一次:

  

在switch语句中,条件仅计算一次,并将结果与​​每个case语句进行比较。在elseif语句中,再次评估条件。如果您的条件比简单比较更复杂和/或处于紧密循环中,则开关可能更快。 ➫➫➫

无需优化。但是,请阅读:
In PHP what's faster, big Switch statement, or Array key lookup

如果要构建配置文件,可以考虑以下内容:

$areas = array
(
  1 => 'abc',
  2 => 'def',
  ..
);

然后简单地比较:

if (!isset($areas[$some_code]))
{
  // do something
}
else
{
  // ok
}

答案 3 :(得分:0)

尝试下面的伪代码

$areas = array('201' => 'New Jersey',
                    '202' => 'Washington',
                    ......
                    ........
                    '999' => '');
function GetAreaName($AreaCode)
{


    if(isset($areas[$AreaCode])) {
        return $areas[$AreaCode];
    } else {
        // do something
    }

}