2010-06-15 2 views
2

Вот фрагмент кода PHP, который я считаю не очень «красивым», я уверен, что его можно упростить с помощью for или что-то в этом роде. Я пытаюсь найти и алгоритм, который будет работать для этого, но я не могу понять это, пожалуйста, помогите мне.PHP: упростить с помощью алгоритма?

Вот код:

if(isset($four)) 
{ 
if(isset($navi[$one][$two][$three][$four])) echo "/content/" . $one . "/" . $two . "/" . $three . "/" .$four . ".php"; 
else echo "error"; 
} 
else if(isset($three)) 
{ 
if(isset($navi[$one][$two][$three])) echo "/content/" . $one . "/" . $two . "/" . $three . ".php"; 
else echo "error"; 
} 
else if(isset($two)) 
{ 
if(isset($navi[$one][$two])) echo "/content/" . $one . "/" . $two . ".php"; 
else echo "error"; 
} 
else if(isset($one)) 
{ 
if(isset($navi[$one]))echo "/content/" . $one . ".php"; 
else echo "error"; 
} 
else 
{ 
echo "error"; 
}

Спасибо!

ответ

2

-Обновлены испытания:

$parts = array($one, $two, $three, $four); 
$reversed = array_reverse($parts); 

function getPath($ret, $n) { 
    global $parts; 
    foreach (range(0, $n) as $i) { 
     $ret = $ret[$parts[$i]]; 
    } 
    return $ret; 
} 

$error = false; 
foreach (range(0, count($reversed)) as $i) { 
    if (!$reversed[$i]) { 
     unset($reversed[$i]); 
     continue; 
    } 

    if (!getPath($navi, count($parts) - $i - 1)) { 
     $error = true; 
     break; 
    } 
} 

if ($error) { 
    echo "error!"; 
} else { 
    echo "/content/" . implode("/", array_reverse($reversed)) . ".php"; 
} 
0

Проблема заключается в том, что вы используете isset(foo), что делает его трудно поместить переменные в массив. Если тестирование длины переменной будет делать, а затем использовать:

$parts = array_reverse(array($one,$two,$three,$four)); 
foreach ($parts as $i => $value) 
    if(strlen($value)==0) 
     unset($array[$i]); 
$final = join('/',parts); 
if(isset($navi[$final])) echo "/content/" . $final . ".php"; 
else echo "\nerror\n\n\n"; 

Но это потребует от вас изменить $ Navi построить выглядеть

$navi['foo/bar/baz'] = "someval"; 

вместо

$navi['foo']['bar']['baz'] = "someval"; 

потому что мы будем использовать конкатенированную строку $final для поиска в $ isset. В противном случае единственным маршрутом является динамически генерируемый php, который является ужасным.

Не могли бы вы структурировать свои данные по-другому? Цикл для измерения массива не является приятным, тогда как вышеприведенный плоский список намного легче выполняется.

0

Я думаю, что с вашим кодом возникают более глубокие проблемы. Но решать именно эту проблему - есть мое предположение:

$urls = array(); 
$tempNavi = $navi; 
foreach (array('one', 'two', 'three', 'four') as $var) { 
    if (!isset($$var) || !isset($tempNavi[$$var])) 
     break; 
    $tempNavi = $tempNavi[$$var]; 
    $urls[] = $$var; 
} 

if ($urls) { 
    echo '/content/' . implode('/', $urls); 
} else { 
    echo 'error'; 
} 
0

Рекурсивное решение, для полноты картины:

function navi_recurse(&$navi, &$steps, $i = 0) { 
    if ($i < count($steps) - 1) { 
    $step = $steps[$i]; 
    if (isset($navi[$step])) 
     return navi_recurse($navi[$step], $steps, $i+1); 
    else 
     return "error\n"; 
    } 
    return '/content/'.implode('/', $steps).'.php'; 
} 

вызовов, как это:

$steps = array($one, $two, $three, $four); 
echo navi_recurse($navi, $steps);