Because I can't help myself, I benchmarked all these answers. @Yoshi's (deleted, but you can see the code below) answer came a fairly clear first, followed by @OliverNybo (about 15% slower), @pr1nc3 (about 35% slower), a gap to mine and @MaximFedorov's first and second answer (about 55-75% slower), then another gap to @TimBiegeleisen and finally to @MaximFedorov's last answer (which didn't actually return the correct result). Here are the results for 100,000 iterations (times in seconds):
Here's the testing code. Note I've removed a call to array_reverse
where it was used as it doesn't do anything other than change the order of output.
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
table {
border-collapse: collapse;align-content:
}
td, th {
border: 1px solid black;
padding: 5px;
}
</style>
</head>
<body>
<pre>
<?php
$string = 'var/log/some/other/directory/file.log';
$elapsed = array();
foreach (array('TimBiegeleisen', 'pr1nc3', 'OliverNybo', 'MaximFedorov1', 'MaximFedorov2', 'MaximFedorov3', 'Nick') as $func) {
$start = explode(' ', microtime());
for ($i = 0; $i < 100000; $i++) $func($string);
$elapsed[$func] = elapsed_time($start);
}
asort($elapsed);
$fastest = min($elapsed);
echo "<table><tr><th>Function</th><th>Elapsed Time</th><th>Delta</tr>";
foreach ($elapsed as $key => $value) {
echo "<td>$key</td><td>$value</td>";
echo "<td>" . sprintf("%.0f%%", ($value - $fastest) / $fastest * 100) . "</td></tr>";
}
echo "</table>\n";
function TimBiegeleisen($input) {
$array = [];
while (preg_match("/\//i", $input)) {
array_push($array, $input);
$input = preg_replace("/\/[^\/]+$/", "", $input);
}
array_push($array, $input);
return $array;
// return array_reverse($array);
}
function pr1nc3($string) {
$array = explode('/', $string);
$i = 0;
foreach ($array as $data) {
$output[] = isset($output) ? $output[$i - 1] . '/' . $data : $data;
$i++;
}
return $output;
}
function OliverNybo($string) {
$array = explode('/', $string);
$last = '';
$output = array();
foreach ($array as $key => $value) {
$result = $last.$value;
$output[$key] = $result;
$last = $result.'/';
}
return $output;
}
function MaximFedorov1($path) {
$output = [];
$pos = strlen($path);
while ($pos !== false) {
$path = substr($path, 0, $pos);
array_unshift($output, $path);
$pos = strrpos($path, '/');
}
return $output;
}
function MaximFedorov2($path) {
$output = [];
do {
array_unshift($output, $path);
$path = dirname($path);
} while ($path !== '.');
return $output;
}
function MaximFedorov3($path) {
$output = [];
$tmp = '';
$len = strrpos($path, '/'); // you can use strlen instead of strrpos,
// but it'll look over filename also
for ($i = 0; $i < $len; $i++) {
if ($path[$i] === '/') {
$output[] = $tmp;
}
$tmp .= $path[$i];
}
$output[] = $path;
return $output;
}
function Nick($string) {
$array = explode('/', $string);
for ($c = count($array); $c > 0; ) {
$output[--$c] = implode('/', $array);
array_pop($array);
}
return $output;
// return array_reverse($output)
}
function Yoshi($input) {
$output = explode('/', $input);
for ($i = 1, $lim = \count($output); $i < $lim; $i++) {
$output[$i] = $output[$i - 1] . '/' . $output[$i];
}
return $output;
}
function elapsed_time(array $start) {
$now = explode(' ', microtime());
$deltasec = $now[1] - $start[1];
$deltamsec = (float)$now[0] - (float)$start[0];
return $deltasec + $deltamsec;
}
?>
</pre>
</body>
</html>