【发布时间】:2011-11-15 16:06:26
【问题描述】:
我正在将递归目录列表中的结果提取到一个数组中,并且想知道是否有更好的(阅读速度更快、更简洁,等等)方法。具体来说,我正在创建一个数组:
path_relative_to_somedir => absolute_path
现在我有:
$map = array();
$base_realpath = realpath('/path/to/dir');
$iterator = new \RecursiveDirectoryIterator($base_realpath);
foreach((new \RecursiveIteratorIterator($iterator)) as $node){
$node_realpath = $node->getRealpath();
$map[substr($node_realpath, strlen($base_realpath) + 1)] = $node_realpath;
}
这很好用(似乎),但我担心边缘情况,虽然我确信它们会在测试中出现,但其他人可能会指出。所以:
- 是否有更好的(读取速度更快、更准确、更可靠)方法来获取相对于
$base_realpath的节点路径? - 我是否应该考虑将
glob()或readdir()等选项作为更快 的替代方案? (这是一个有点时间敏感的操作,我看到一个与 PHP 中的目录递归有关的问题,答案中有一些基准,找到时会链接)
--问题结束--
--可能是不必要的细节开始--
目的;我正在为应用程序创建一个虚拟工作目录,以便对给定文件的调用映射到实际文件。例如:(我正在详细说明,以防有人根据我实际在做的事情有一个整体更好的替代方法)
鉴于dir1 是虚拟工作目录的“根”,我们希望合并到dir2:
path/ path/
| |
+-- to/ +-- to/
| |
+-- dir1/ +-- dir2/
| |
+-- script1.php +-- script2.php
| |
+-- script2.php +-- subdir/
| |
+-- subdir/ +-- script4.php
|
+-- script3.php
它会产生一个像这样的数组:
[script1.php] => path/to/dir1/script1.php
[script2.php] => path/to/dir2/script2.php
[subdir/script3.php] => path/to/dir1/subdir/script3.php
[subdir/script4.php] => path/to/dir2/subdir/script4.php
请注意,合并替换了现有的相对路径,并且每个元素都映射到它的实际路径。我这里只是用array_replace(),这里是sn-p的方法:
public function mergeModule($name){
$path = realpath($this->_application->getPath() . 'modules/' . $name);
if(!is_dir($path) || !is_readable($path)){
// @todo; throw exception
}
$map = array();
try{
$directory_iterator = new \RecursiveDirectoryIterator($path);
foreach((new \RecursiveIteratorIterator($directory_iterator)) as $node){
$node_realpath = $node->getRealpath();
$map[substr($node_realpath, strlen($path) + 1)] = $node_realpath;
}
}catch(\Exception $exception){
// @todo; handle
}
$this->_map = array_replace($this->_map, $map);
}
【问题讨论】:
-
您的示例在“to”目录中有 script2.php,而不是与您产生的输出冲突的“dir2”目录。你能解决这个问题吗?
-
哎呀,谢谢@hafichuk - 修复。
-
这几乎不值得一提,但请记住 PHP 不容易优化,因此值得在循环外缓存
strlen($base_realpath) + 1之类的值。我假设strlen是一个简单的O(1)操作,但如果你做了很多,即使是函数调用也会累加。 -
@Matthew - 确实如此;我实际上在 SO 编辑框中重新键入了该功能,我通常会采取这种预防措施。实际上,我想知道获取给定资源的相对路径的最佳方法是什么(slice
path/to/dirfrompath/to/dir/subdir1/file2.php- 我可以使用字符串长度,还是应该做一些更直观的事情? i>) -
@Bracketworks,简而言之,我认为您收集文件列表的方式没有什么特别的问题。这与我将使用的技术相同,包括使用
substr来获取相对路径。如果您担心速度,那就尝试一下并做一些基准测试,但无论您选择使用哪种 API,底层 I/O 都应该是瓶颈。
标签: php path directory-structure