Created
September 9, 2011 01:11
-
-
Save ruthlessfish/1205239 to your computer and use it in GitHub Desktop.
convert an array of files into a multi-dimensional array
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Build Manifest | |
* | |
* Requires: PHP 5.3+ | |
* | |
* Takes an array of file names and builds a multi-dimensional array | |
* representing a simple file-system. | |
* | |
* NOTE: Files are only currently supported as leaf elements in the array. | |
* For example, if the files array contains '/var/www/html' it will | |
* create a file called 'html' in the /var/www/ directory. | |
* | |
* Example Use Case: | |
* | |
* I am building a web interface for Mercurial repositories and I want | |
* to be able to show the files from any specified revision in a tree view. | |
* From Mercurial we can call `hg manifest -r REV` and we will get back a list | |
* of files that we can split on the newline character. We can then pass this array | |
* on to build_manifest() to get a more tree-friendly data structure. | |
* | |
* $files = explode("\n", `hg manifest /path/to/your/repository`); | |
* $files_arr = build_manifest($files); | |
* | |
* | |
*/ | |
function build_manifest ($files = array()) | |
{ | |
// break each file up into segments | |
$files = array_map(function($file) { | |
return explode('/', $file); | |
}, $files); | |
// doc root | |
$manifest = array(); | |
foreach ($files as $file) | |
{ | |
_build_file($file, $manifest); | |
} | |
return $manifest; | |
} | |
// helper function | |
// recursively save file parts in to an array | |
function _build_file($file, &$parent) | |
{ | |
$i = count($file) - 1; // current index | |
$seg = array_shift($file); // next segment | |
if ($i < 0) | |
{ | |
throw new Exception('Invalid file name.'); | |
} | |
// add the file to the directory | |
if ($i === 0) | |
{ | |
// prevent duplicates | |
in_array($seg, $parent) OR $parent[] = $seg; | |
return; | |
} | |
// create the subdirectory if it does not yet exist | |
isset($parent[$seg]) OR $parent[$seg] = array(); | |
return _build_file($file, $parent[$seg]); | |
} | |
// ------------------------------------------------------------------------ | |
// Test | |
$files = array('readme.txt', | |
'foo.txt', | |
'foo/bar.txt', | |
'foo/bar/baz.txt', | |
'foo/bar/baz/foo.txt', | |
'foo/bar/baz/bar.txt', | |
'foo/bar/baz/baz.txt', | |
'bar.txt', | |
'bar/baz.txt', | |
'bar/baz/foo.txt', | |
'bar/baz/foo/foo.txt', | |
'bar/baz/foo/bar.txt', | |
'bar/baz/foo/baz.txt', | |
'baz.txt', | |
'baz/foo.txt', | |
'baz/foo/bar.txt', | |
'baz/foo/bar/foo.txt', | |
'baz/foo/bar/bar.txt', | |
'baz/foo/bar/baz.txt'); | |
print_r(build_manifest($files)); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Output | |
Array | |
( | |
[0] => readme.txt | |
[1] => foo.txt | |
[foo] => Array | |
( | |
[0] => bar.txt | |
[bar] => Array | |
( | |
[0] => baz.txt | |
[baz] => Array | |
( | |
[0] => foo.txt | |
[1] => bar.txt | |
[2] => baz.txt | |
) | |
) | |
) | |
[2] => bar.txt | |
[bar] => Array | |
( | |
[0] => baz.txt | |
[baz] => Array | |
( | |
[0] => foo.txt | |
[foo] => Array | |
( | |
[0] => foo.txt | |
[1] => bar.txt | |
[2] => baz.txt | |
) | |
) | |
) | |
[3] => baz.txt | |
[baz] => Array | |
( | |
[0] => foo.txt | |
[foo] => Array | |
( | |
[0] => bar.txt | |
[bar] => Array | |
( | |
[0] => foo.txt | |
[1] => bar.txt | |
[2] => baz.txt | |
) | |
) | |
) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment