Reputation: 85
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!
Upvotes: 2
Views: 273
Reputation: 338148
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);
Upvotes: 0
Reputation: 4297
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';
}
Upvotes: 0
Reputation: 12517
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";
}
Upvotes: 2
Reputation: 20131
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.
Upvotes: 0