虽然目前大部分公司使用PHP的场景不会去读取目录,但在一些笔试题中还是会出现这样的题目,算是考基本功的一些体现吧。
知识点:
最方便的方法是使用语言自带的scandir
函数:1
2$files = scandir('/usr/local/etc/nginx');
print_r($files);
但是一些虚拟主机的提供者由于安全原因会禁用掉scandir
函数,可以使用opendir
相关函数来处理:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16$dir = '/usr/local/etc/nginx/';
function customScanDir($dir, $level = 0)
{
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
echo str_repeat(' ', 2 * $level) . $file . "\n";
if (is_dir($dir . DIRECTORY_SEPARATOR . $file) && $file !== '.' && $file !== '..') {
customScanDir($dir . DIRECTORY_SEPARATOR . $file, $level + 1);
}
}
closedir($dh);
}
}
}
customScanDir($dir);
还有一种方法是使用SPL提供的DirectoryIterator
迭代器来实现。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37$topPath = '/usr/local/etc/nginx';
function customReadDir($path, $level = 0)
{
if ($level > 5) {
return false;
}
if (!is_dir($path)) {
throw new Exception($path . ' is not a folder');
}
if (!is_readable($path)) {
echo 'No permission to ' . $path . "\n";
return false;
}
$dirIterator = new DirectoryIterator($path);
foreach ($dirIterator as $file) {
$fileName = $file->getFilename();
$absPath = $path . DIRECTORY_SEPARATOR . $fileName;
if ($fileName === '.' || $fileName === '..') {
continue;
}
if (is_dir($absPath)) {
echo str_repeat(' ', $level * 2) . '|- ' . "\033[34m" . $fileName . "\033[0m\n";
} else {
echo str_repeat(' ', $level * 2) . '|- ' . $fileName . "\n";
}
if (is_dir($absPath)) {
customReadDir($absPath, $level + 1);
}
}
}
customReadDir($topPath);