2

Here's a piece of PHP code I think is not very "pretty", I'm sure it's possible to simplify it with for or something. I'm trying to find and algorithm that would work for this, but I can't figure it out, please help me.

Here's the code:

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";
}

Thanks!

4 Answers 4

2

Updated, tested:

$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";
}
Sign up to request clarification or add additional context in comments.

Comments

0

The problem is that you are using isset(foo), which makes it hard to put the variables into an array. If testing the length of the variable will do, then use:

$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";

But this will require you to change your $navi construct to look like

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

instead of

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

because we will be using the concatenated string $final to look up in the $isset. Otherwise the only route is dynamically generated php which is horrible.

Could you structure your data differently? Looping for array dimensions is not nice, whereas the above flat list is much more easily accomplished.

Comments

0

I think there is deeper problems with Your code. But to solve just this problem -- there is my guess:

$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';
}

Comments

0

A recursive solution, for the sake of completeness:

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';
}

Call like this:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.